面试题答案
一键面试1. 信号集操作函数
- sigemptyset:初始化一个空的信号集。
- sigaddset:将指定信号添加到信号集中。
- sigprocmask:设置当前进程的信号掩码,用于阻塞或解除阻塞信号。
- sigwait:等待信号集中的信号到达。
2. 线程同步机制
使用互斥锁(pthread_mutex_t
)来避免竞态条件。在访问共享资源(如信号处理相关的变量)时,先锁定互斥锁,操作完成后解锁。
3. 完整代码示例
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
// 互斥锁
pthread_mutex_t mutex;
// 用于主线程的信号集
sigset_t main_signal_set;
// 用于工作线程的信号集
sigset_t worker_signal_set;
// 工作线程函数
void* worker_thread(void* arg) {
int signum;
// 等待SIGUSR1信号
while (1) {
pthread_mutex_lock(&mutex);
int res = sigwait(&worker_signal_set, &signum);
pthread_mutex_unlock(&mutex);
if (res != 0) {
printf("sigwait failed\n");
pthread_exit(NULL);
}
if (signum == SIGUSR1) {
printf("Worker thread received SIGUSR1. Performing specific task...\n");
}
}
}
int main() {
pthread_t worker_tid;
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 初始化主线程信号集
sigemptyset(&main_signal_set);
sigaddset(&main_signal_set, SIGTERM);
// 初始化工作线程信号集
sigemptyset(&worker_signal_set);
sigaddset(&worker_signal_set, SIGUSR1);
// 设置主线程信号掩码,阻塞SIGTERM
pthread_sigmask(SIG_BLOCK, &main_signal_set, NULL);
// 设置工作线程信号掩码,阻塞SIGUSR1
pthread_sigmask(SIG_BLOCK, &worker_signal_set, NULL);
// 创建工作线程
if (pthread_create(&worker_tid, NULL, worker_thread, NULL) != 0) {
printf("\n ERROR creating thread");
return 1;
}
int signum;
// 主线程等待SIGTERM信号
while (1) {
pthread_mutex_lock(&mutex);
int res = sigwait(&main_signal_set, &signum);
pthread_mutex_unlock(&mutex);
if (res != 0) {
printf("sigwait failed\n");
return 1;
}
if (signum == SIGTERM) {
printf("Main thread received SIGTERM. Shutting down gracefully...\n");
break;
}
}
// 等待工作线程结束
pthread_join(worker_tid, NULL);
// 清理互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
4. 代码说明
- 初始化信号集:分别为
main_signal_set
和worker_signal_set
初始化并添加相应信号。 - 设置信号掩码:通过
pthread_sigmask
阻塞主线程的SIGTERM
信号和工作线程的SIGUSR1
信号,避免信号在设置处理函数前被意外处理。 - 创建线程:创建工作线程,在工作线程中通过
sigwait
等待SIGUSR1
信号。 - 主线程处理:主线程通过
sigwait
等待SIGTERM
信号,接收到信号后执行优雅关闭操作。 - 互斥锁使用:在调用
sigwait
时,使用互斥锁来避免在信号等待过程中可能出现的竞态条件。