linux - Fork() 带有信号的子进程
问题描述
我必须派生两个阻止 SIGINT 命令的子进程,但其中一个应该在接收到 SIGTERM 信号时取消阻止它,而另一个子进程和父进程由于相同的 SIGTERM 信号而打印它们的 PID。第二个子进程应立即终止,但父进程应等待其子进程结束然后停止。
我刚开始在 Linux 中学习 C 编程,我并不真正了解分叉和信号是如何工作的。据我了解,到目前为止我编写的这段代码将分叉一个进程,并且子进程将阻止 Ctrl-C 命令,除非我用 kill -9 pid杀死它,否则整个过程将永远运行。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void handler(int n) {
write(STDOUT_FILENO, "I won't die!! Haha\n",13);
}
int main()
{
pid_t pid = fork();
if (pid < 0) {
perror("Fork() error!");
exit(-1);
}
if (pid == 0)
signal(SIGINT,handler);
while(1) {
printf("Wasting the iteration. %d\n", getpid());
sleep(1);
}
return 0;
}
- 我如何使用 SIGTERM?我应该在哪里称呼它?
- 如何让父进程创建另一个阻止 Ctrl-C 命令的子进程?
解决方案
不确定是否要分叉多个进程,因为我从未这样做过。就 SIGTERM 而言,您需要一个回调来处理终止信号。以下是我在编写的许多服务中使用的一个:
/***************************************************************************************************
* Function signal_callback_handler - allows for a graceful shutdown process.
* *************************************************************************************************/
void signal_callback_handler(int signum) {
//here we receive some sort of notification to terminate.
//Log this event and change the state of the process control variable
//so that the main processing loop knows to stop
syslog(LOG_NOTICE, "Recived signal to shutdown - Signal %d", signum);
//put code here to do preshutdown clean up, terminating threads, etc....
}
然后,您需要为要处理的每个终止信号注册回调。以下是我在 fork 之前放在 main 函数中的那些:
if (signal(SIGINT, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGINT signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGUSR1, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGUSR1 signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGUSR2, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGUSR signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGTERM, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGTERM signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGTSTP, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGTSTP signal handler.");
return(EXIT_FAILURE);
}
推荐阅读
- html - 如何根据拨动开关设置使元素消失
- c# - 如何禁用 Blazor 中的组件层次结构?
- c++ - 错误:没有匹配的成员函数调用“推送”
- mongodb - 为什么要在 mongoDB 中间件的回调中使用异步函数?
- javascript - Reg Exp 用于查找主题标签词
- javascript - 带有和不带有滚动的元素会有所不同
- css - Bootstrap 4:在父 div 中拟合图像内容
- javascript - 为什么 css @media print 在某些 div 上不起作用
- docker-swarm - traefik 搬运工群 404
- python - 成员是缺少错误的必需参数