关键操作步骤说明
- 信号处理函数的定义:
- 定义主线程用于清理资源的信号处理函数,例如对于
SIGTERM
信号,在处理函数中进行资源清理操作。
- 定义子线程用于处理业务相关信号(如
SIGUSR1
)的信号处理函数,在处理函数中完成相应业务逻辑。
- 信号集的初始化:
- 创建一个信号集用于阻塞信号,初始化该信号集,将需要处理的信号(如
SIGTERM
、SIGUSR1
)添加到信号集中。
- 主线程操作:
- 在主线程初始化资源之前,使用
sigprocmask
函数将信号集设置为阻塞状态,防止信号在资源未初始化完成时干扰。
- 初始化资源。
- 解除对信号的阻塞,使主线程能够接收信号并调用相应的信号处理函数进行资源清理。
- 子线程操作:
- 子线程在启动时,同样使用
sigprocmask
函数将信号集设置为阻塞状态。
- 子线程执行核心业务逻辑。
- 在业务逻辑中,使用
sigwait
函数等待特定信号(如SIGUSR1
),当信号到达时,sigwait
函数返回,子线程调用相应的信号处理函数处理信号。
代码框架
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
// 信号处理函数声明
void handle_term(int signum);
void handle_usr1(int signum);
// 全局变量,假设为需要清理的资源
int resource = 0;
void* thread_function(void* arg) {
sigset_t *set = (sigset_t *)arg;
int signum;
// 子线程阻塞信号
if (sigprocmask(SIG_SETMASK, set, NULL) == -1) {
perror("sigprocmask");
pthread_exit(NULL);
}
// 核心业务逻辑
while (1) {
// 等待SIGUSR1信号
if (sigwait(set, &signum) != 0) {
perror("sigwait");
pthread_exit(NULL);
}
if (signum == SIGUSR1) {
handle_usr1(signum);
}
}
pthread_exit(NULL);
}
int main() {
pthread_t tid;
sigset_t set;
// 初始化信号集
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGUSR1);
// 主线程阻塞信号
if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
perror("sigprocmask");
return 1;
}
// 初始化资源
resource = 1;
// 创建子线程
if (pthread_create(&tid, NULL, thread_function, (void *)&set) != 0) {
perror("pthread_create");
return 1;
}
// 主线程解除对信号的阻塞
if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) {
perror("sigprocmask");
return 1;
}
// 注册信号处理函数
struct sigaction sa_term;
sa_term.sa_handler = handle_term;
sigemptyset(&sa_term.sa_mask);
sa_term.sa_flags = 0;
if (sigaction(SIGTERM, &sa_term, NULL) == -1) {
perror("sigaction");
return 1;
}
struct sigaction sa_usr1;
sa_usr1.sa_handler = handle_usr1;
sigemptyset(&sa_usr1.sa_mask);
sa_usr1.sa_flags = 0;
if (sigaction(SIGUSR1, &sa_usr1, NULL) == -1) {
perror("sigaction");
return 1;
}
// 主线程等待子线程结束
if (pthread_join(tid, NULL) != 0) {
perror("pthread_join");
return 1;
}
return 0;
}
void handle_term(int signum) {
// 清理资源
printf("Handling SIGTERM, cleaning up resource...\n");
resource = 0;
}
void handle_usr1(int signum) {
// 处理SIGUSR1信号相关业务逻辑
printf("Handling SIGUSR1 in sub - thread...\n");
}