gpt4 book ai didi

c - 在子进程中使用信号

转载 作者:行者123 更新时间:2023-12-04 15:47:21 24 4
gpt4 key购买 nike

我想创建一个简单的程序,它使用 fork 并创建一个使用 pause 等待的子进程。我希望这个子进程在从父进程收到特定信号后启动。我写的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
pid_t c = fork();
if (c == 0) {
pause();
printf("signal was given");
}
if (c > 0)
kill(c, SIGINT);

return 0;
}

我认为 kill 会向 pid c(child) 的进程发出特定信号,而我认为 pause 只是等待取消暂停该进程的信号。但是在这种情况下运行这个程序没有结果。我还尝试使用 signal(SIGINT, handler) 向子进程添加一个信号捕获函数,并创建一个打印所需结果的处理函数,但它仍然无法正常工作。有什么想法吗?

最佳答案

如果您发送 SIGINT(其默认配置是终止进程)到既不阻止它也不处理它​​的进程,则该进程将终止。

如果你想让信号中断像pause()这样的阻塞调用,它需要有一个处理程序。

但是简单地安装处理程序会引入竞争条件:

if (c == 0 ){
//< if the signal arrives here the child dies
signal(SIGINT, handler);
//< if the signal arrives here then nothing happens except the handler is run
pause(); //< if the handler arrives here then pause gets interrupted
printf("signal was given\n");
exit(0);
}

要消除竞争条件,您需要

  1. 在 parent 中阻止信号,以便 child 从信号被阻止开始
  2. 在 child 中安装处理程序
  3. 在一个原子步骤中解锁信号和pause()

一步实现3.需要sigsuspend()而不是pause()

#include <stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<signal.h>

void handler(int Sig){}

int main()
{
sigset_t sigint, oldmask; sigemptyset(&sigint); sigaddset(&sigint, SIGINT);
sigprocmask(SIG_BLOCK, &sigint, &oldmask);

pid_t c=fork();
if(0>c) return perror(0),1;
if (c==0){
signal(SIGINT, handler);
sigdelset(&oldmask,SIGINT); /*in (the unlikely) case the process started with SIGINT blocked*/
sigsuspend(&oldmask);
printf("signal was given\n");
exit(0);
}
kill(c,SIGINT);
wait(0);
return 0;
}

或者,您可以使用 sigwait() 并完全放弃对处理程序的需要:

#include <stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<signal.h>

int main()
{
sigset_t sigint, oldmask; sigemptyset(&sigint); sigaddset(&sigint, SIGINT);
sigprocmask(SIG_BLOCK, &sigint, &oldmask);

pid_t c=fork();
if(0>c) return perror(0),1;
if (c==0){
int sig; sigwait(&sigint,&sig);
printf("signal was given\n");
exit(0);
}
kill(c,SIGINT);
wait(0);
return 0;
}

关于c - 在子进程中使用信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55190460/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com