如何用C语言同步两个进程(子进程和父进程)的信号?
我想用信号SIGUSR1来同步C中的进程。我想让父进程发出信号,当接收到这个信号时,将相同的信号发送给子进程。我写了一小段来激发推理,但它并没有消失如何用C语言同步两个进程(子进程和父进程)的信号?,c,process,signals,C,Process,Signals,我想用信号SIGUSR1来同步C中的进程。我想让父进程发出信号,当接收到这个信号时,将相同的信号发送给子进程。我写了一小段来激发推理,但它并没有消失 #include <sys/types.h> #include <signal.h> #include <stdio.h> #include <unistd.h> void trataSIGUSR1(int sigNum) { printf("SIGUSR1\n"); } int ma
#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();
}
}
简单提示是使用pause和kill,即pause用于阻止进程执行,直到接收到任何信号,一旦接收到信号,则执行某些操作,kill用于发送SIGUSR1信号
此外,当您使用pause时,它将暂停进程,直到收到任何信号为止,对于该信号,默认操作应为用户定义的ISR。从暂停的手动页面
返回值
仅当捕捉到信号并返回信号捕捉功能时,暂停才会返回。
在这种情况下,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;
}
旁注,用于在收到SIGUSR1时在trataSIGINT中设置标志,而不是声明int nSIGINT=0;将标志变量声明为volatile sigu原子类型的类型
根据ISO/IEC 9899:2011§7.14.1.1,信号功能
如果信号不是由于调用中止或
raise函数,如果信号处理程序
指具有静态或线程存储持续时间的任何对象
不是无锁原子对象,除非通过将值指定给
对象声明为volatile sig_atomic_t或信号处理程序
调用标准库中除中止以外的任何函数
函数、退出函数、快速退出函数或
第一个参数等于信号编号的信号函数
对应于导致调用处理程序的信号。
此外,如果对信号函数的这种调用导致
SIG_ERR return,errno的值不确定。252
252如果异步信号处理程序生成任何信号,则
行为是未定义的
也许试着在家长中等待信号,然后试着向家长发送信号。我怎么做?我不知道如何等待信号,我不想用忙碌的等待。你能告诉我怎么用这个吗?我可以设置一个特殊的信号,以便在暂停后继续代码?尝试sigaction-检查并更改信号操作。要了解更多详细信息,只需键入man sigaction。请注意,如果收到任何信号,pause都会返回i。您可能希望将其放入一个循环中,以检查接收到的volatile int usr1_;并在SIGUSR1的信号处理程序中将其设置为true。并避免任何已经使用SIGUSR1本身的库。最好使用posix互斥量和条件。是true@GoswinvonBrederlow或volatile-sigatomic_t usr1_-received;最好是始终以原子方式访问sigatomic_t类型,并避免中断变量访问的不确定性。什么是kill0,SIGUSR1?它应该是killpid,SIGUSR1;为什么要在父进程中暂停?删除它,一个接一个。请说明否决投票的原因。
//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;
}