面试题答案
一键面试实现思路
- 主线程阻塞信号:主线程使用
sigprocmask
函数阻塞SIGTERM
信号,防止主线程在处理其他任务时意外响应SIGTERM
。 - 子线程处理信号:子线程使用
pthread_sigmask
函数设置为不阻塞SIGTERM
信号,同时创建一个信号处理函数,当SIGTERM
信号到达时,子线程能够捕获并执行清理工作。
主要代码逻辑
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
// 信号处理函数
void sig_handler(int signum) {
printf("子线程收到SIGTERM信号,开始清理工作...\n");
// 在这里添加清理代码
}
void* thread_func(void* arg) {
// 子线程设置为不阻塞SIGTERM信号
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGTERM);
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
// 注册信号处理函数
struct sigaction sa;
sa.sa_handler = sig_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
// 模拟子线程工作
while (1) {
printf("子线程正在工作...\n");
sleep(1);
}
return NULL;
}
int main() {
pthread_t tid;
// 主线程阻塞SIGTERM信号
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGTERM);
sigprocmask(SIG_BLOCK, &sigset, NULL);
// 创建子线程
pthread_create(&tid, NULL, thread_func, NULL);
// 主线程模拟其他工作
while (1) {
printf("主线程正在工作...\n");
sleep(1);
}
// 等待子线程结束(这里不会执行到,因为主线程在while循环中)
pthread_join(tid, NULL);
return 0;
}
在上述代码中:
- 主线程:通过
sigprocmask
函数阻塞SIGTERM
信号,然后创建子线程。 - 子线程:首先通过
pthread_sigmask
函数设置为不阻塞SIGTERM
信号,接着注册sig_handler
函数作为SIGTERM
信号的处理函数,然后模拟子线程的工作。当收到SIGTERM
信号时,sig_handler
函数会被调用执行清理工作。