实现思路
- 初始化信号屏蔽集:在程序开始时,创建一个信号屏蔽集并添加SIGTERM信号。
- 主线程临时屏蔽信号:主线程在需要时调用
sigprocmask
函数来临时屏蔽SIGTERM信号。
- 子线程特定任务屏蔽信号:子线程在执行特定任务前,调用
pthread_sigmask
函数屏蔽SIGTERM信号,任务完成后再调用pthread_sigmask
恢复对信号的响应。
关键代码片段
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
sigset_t sigSet;
void* threadFunction(void* arg) {
// 子线程屏蔽SIGTERM信号
pthread_sigmask(SIG_BLOCK, &sigSet, NULL);
// 特定任务
printf("子线程执行特定任务\n");
sleep(2);
// 子线程恢复对SIGTERM信号的响应
pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL);
return NULL;
}
int main() {
pthread_t thread;
// 初始化信号屏蔽集,添加SIGTERM信号
sigemptyset(&sigSet);
sigaddset(&sigSet, SIGTERM);
// 主线程临时屏蔽SIGTERM信号
sigprocmask(SIG_BLOCK, &sigSet, NULL);
// 创建子线程
if (pthread_create(&thread, NULL, threadFunction, NULL) != 0) {
perror("pthread_create");
return 1;
}
// 主线程特定操作
printf("主线程执行操作\n");
sleep(2);
// 主线程恢复对SIGTERM信号的响应
sigprocmask(SIG_UNBLOCK, &sigSet, NULL);
// 等待子线程结束
if (pthread_join(thread, NULL) != 0) {
perror("pthread_join");
return 1;
}
return 0;
}
可能遇到的同步问题及解决方案
- 同步问题:主线程和子线程可能在信号屏蔽和恢复的时机上出现竞争条件,导致信号在不期望的时刻被处理。
- 解决方案:
- 使用互斥锁(
pthread_mutex_t
)来保护对信号屏蔽集的操作,确保在同一时间只有一个线程可以修改信号屏蔽集。
- 使用条件变量(
pthread_cond_t
)来同步主线程和子线程的操作,例如在主线程等待子线程完成特定任务后再恢复对信号的响应。
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
sigset_t sigSet;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int taskCompleted = 0;
void* threadFunction(void* arg) {
// 子线程屏蔽SIGTERM信号
pthread_mutex_lock(&mutex);
pthread_sigmask(SIG_BLOCK, &sigSet, NULL);
pthread_mutex_unlock(&mutex);
// 特定任务
printf("子线程执行特定任务\n");
sleep(2);
// 任务完成
pthread_mutex_lock(&mutex);
taskCompleted = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
// 子线程恢复对SIGTERM信号的响应
pthread_mutex_lock(&mutex);
pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t thread;
// 初始化信号屏蔽集,添加SIGTERM信号
sigemptyset(&sigSet);
sigaddset(&sigSet, SIGTERM);
// 主线程临时屏蔽SIGTERM信号
pthread_mutex_lock(&mutex);
sigprocmask(SIG_BLOCK, &sigSet, NULL);
pthread_mutex_unlock(&mutex);
// 创建子线程
if (pthread_create(&thread, NULL, threadFunction, NULL) != 0) {
perror("pthread_create");
return 1;
}
// 主线程等待子线程任务完成
pthread_mutex_lock(&mutex);
while (!taskCompleted) {
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
// 主线程恢复对SIGTERM信号的响应
pthread_mutex_lock(&mutex);
sigprocmask(SIG_UNBLOCK, &sigSet, NULL);
pthread_mutex_unlock(&mutex);
// 等待子线程结束
if (pthread_join(thread, NULL) != 0) {
perror("pthread_join");
return 1;
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}