设计思路
- 信号处理函数注册:使用
signal
或 sigaction
函数注册不同信号的处理函数。sigaction
更灵活,推荐使用。
- 数据共享:通过全局变量在不同信号处理函数间共享数据。
- 同步:使用互斥锁(
pthread_mutex_t
)来保证不同信号处理函数对共享数据的访问同步。
- 避免干扰:信号处理函数应尽量简短,复杂操作可通过设置标志位,在主循环中处理。
关键代码片段
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
// 共享数据
int shared_variable = 0;
pthread_mutex_t mutex;
// SIGTERM 处理函数
void handle_sigterm(int signum) {
pthread_mutex_lock(&mutex);
// 进行优雅关闭的逻辑,例如清理资源
printf("Received SIGTERM, performing graceful shutdown...\n");
// 可以设置标志位,让主循环进行具体清理
pthread_mutex_unlock(&mutex);
}
// SIGCHLD 处理函数
void handle_sigchld(int signum) {
pthread_mutex_lock(&mutex);
// 处理子进程状态变化,例如回收子进程资源
printf("Received SIGCHLD, handling child process status change...\n");
// 可在这里更新共享数据
pthread_mutex_unlock(&mutex);
}
// SIGALRM 处理函数
void handle_sigalrm(int signum) {
pthread_mutex_lock(&mutex);
// 定期执行某些任务
printf("Received SIGALRM, performing periodic task...\n");
// 更新共享数据
shared_variable++;
pthread_mutex_unlock(&mutex);
}
int main() {
struct sigaction sa;
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 注册 SIGTERM 信号处理函数
sa.sa_handler = handle_sigterm;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
// 注册 SIGCHLD 信号处理函数
sa.sa_handler = handle_sigchld;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGCHLD, &sa, NULL);
// 注册 SIGALRM 信号处理函数
sa.sa_handler = handle_sigalrm;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
// 设置定时器,定期发送 SIGALRM 信号
alarm(5);
// 主循环
while (1) {
pthread_mutex_lock(&mutex);
// 主循环可以检查共享数据并进行相应处理
printf("Shared variable: %d\n", shared_variable);
pthread_mutex_unlock(&mutex);
sleep(1);
}
// 清理互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}