c - How to sync two process (child and parent) with signals in C?
问题描述
I want use signal (SIGUSR1) to sync process in C. I want that parent process wainting for a signal, when receive this signal, send the same signal to child process. I wrote a short paragraph to stimulate reasoning, but it does not go away.
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void trataSIGUSR1(int sigNum) {
printf("SIGUSR1\n");
}
int main(void) {
pid_t pid;
struct sigaction sa;
pid = fork();
if (pid == 0) {
struct sigaction sa = {0};
sa.sa_handler = trataSIGUSR1;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1,&sa,NULL);
pause();
printf("This never execute");
} else {
printf("I'am father: %d!\n",getppid());
kill(0,SIGUSR1);
pause();
}
}
OUTPUT
I'am father: 12082!
User defined signal 1: 30
解决方案
使用简单提示pause()
,kill()
即pause()
用于阻止进程执行直到收到任何信号,一旦收到信号,然后do_something()
用于kill()
发送SIGUSR1
信号。
此外,当您使用 时pause()
,它会暂停进程,直到收到任何信号,并且对于该信号,默认操作应该是用户定义的 ISR。从手册页pause()
RETURN VALUE
pause()
仅在 asignal was caught
和 返回时signal-catching function
返回。在这种情况下 pause() 返回 -1,并且 errno 设置为 EINTR。
这是示例所需的示例代码
//int nSIGINT = 0; /* declare variable of type volatile sigatomic_t */
volatile sigatomic_t nSIGINT;
void trataSIGINT(int sigNum) {
nSIGINT = 1;/* set the flag as needed */
}
int main(void ){
int pid;
pid=fork();/* create child process */
if(pid==0) {
//signal(SIGUSR1,trataSIGINT);/* instead of signal() use sigaction */
struct sigaction sa = {0}; /* initialize sa or fill all its members*/
sa.sa_handler = trataSIGINT;/* set the handler to trataSIGINT*/
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1,&sa,NULL); /* when child received SIGUSR1, trataSIGINT gets called */
pause(); /* wait until any signal received */
/* do_something_child() code, this you want to run only after receiving signal */
}
else {
/* do_something_parent() */
printf("parent about to send user signal to child\n");
kill(pid,SIGUSR1); /*send SIGUSR1 to child */
wait(0); /* wait till child completes */
}
return 0;
}
旁注,用于在收到时设置标志,而不是将trataSIGINT()
声明标志变量声明为类型类型。SIGUSR1
int nSIGINT = 0;
volatile sigatomic_t
来自 ISO/IEC 9899:2011 §7.14.1.1
signal
功能¶5 如果信号不是作为调用
abort
or 函数的结果而出现的,则如果信号处理程序引用任何具有或线程存储持续时间的对象,而不是通过为声明为的对象分配一个值raise
,则行为未定义,或者信号处理程序调用标准库中的任何函数,而不是 函数、函数、函数或信号函数,其第一个参数等于与导致调用处理程序的信号对应的信号编号。此外,如果对信号函数的这种调用导致 返回,则 的值是不确定的。252)static
lock-free atomic object
volatile sig_atomic_t
abort
_Exit
quick_exit
SIG_ERR
errno
252) 如果任何信号由异步信号处理程序生成,则行为为
undefined
。
推荐阅读
- c - 为什么在 C 中进行类型转换需要括号?
- r - 在 data.frame 中包含 IRange 列表作为列
- javascript - 当所有代码都在一个脚本标签中时,为什么这个脚本不会执行?
- indexing - 试图以不同的模式将数据从一张纸复制到另一张纸
- django - Django (2.0.1) 行 SQL 查询 - 将结果放入模板 Html *原始查询必须包含主键*
- javascript - 在 Chrome 开发者工具中调试时拆分冗长 JavaScript 的任何方法
- php - 如何在 PHP 中将 stdClass 对象转换为 int
- java - 如何在没有为您解析单词的数组或方法的情况下找到字符串中最长的单词
- java - 在重复值的簇字符串中以与它们在原始字符串中出现的相同顺序分隔字符串
- c# - Autofac 如何处理非一次性组件