我不明白以下代码:
pid_t pid;
int counter = 0;
void handler1(int sig) {
counter++;
printf("counter = %d\n", counter);
fflush(stdout);
kill(pid, SIGUSR1);
}
void handler2(int sig) {
counter += 3;
printf("counter = %d\n", counter);
exit(0);
}
int main() {
signal(SIGUSR1, handler1);
if ((pid = fork()) == 0) {
signal(SIGUSR1, handler2);
kill(getppid(), SIGUSR1);
while (1) {
};
} else {
pid_t p;
int status;
if ((p = wait(&status)) > 0) {
counter += 2;
printf("counter = %d\n", counter);
}
}
}
在父进程等待其子进程终止之前,子进程如何实际杀死父进程?
首先请注意,kill()
系统调用的名称有些错误,因为它是用于将信号发送到进程的通用函数。终止目标进程只是几种可能结果中的一种。
但是,更一般而言,信号处理是一种中断机制。大量的库函数,包括wait()
可以通过接收信号中断的函数。控制将该信号传递给已注册的处理程序(如果有),否则将执行默认操作。之后,被中断的函数将返回,并通过其返回代码和/或通过设置来指示错误errno
。
编辑添加:此外,您自己的代码可能会由于收到信号而中断。如果效果不是终止进程,则如果信号处理程序正常退出,则在中断处继续执行;如果通过调用退出处理程序,则在其他处恢复执行longjmp()
。
同样,信号传递是内核处理的异步机制。进程可能被阻塞或以其他方式占用并仍接收信号;确实,这是他们重点的重要组成部分。每个进程都有一个等待处理的待处理信号队列;对于大多数进程,此队列几乎一直都是空的,但是除非您显式阻止信号,否则一个进程假定它不会接收任何信号(并且始终无法阻止某些信号)永远是不安全的。
在您的特定代码中,主进程从设置function1()
为signal的处理程序开始USR1
。然后进行分叉,子进程集将函数function2()
用作其信号处理程序USR1
(不影响父进程),将信号发送USR1
给父进程,并进入无限循环。
同时,父wait()
进程为其子进程启动一个。这将通过接收信号而中断。在收到信号并运行注册的处理程序之后,等待将结束,wait()
返回-1并设置errno
为EINTR
。处理程序执行的动作之一是将a发送SIGUSR1
给孩子。
收到信号后,孩子的正常执行流程将中断以运行其处理程序function2()
。这将更新子级的变量副本counter
,打印其值,然后输出exit()
s。
最终结果:
主要过程打印
计数器= 1
然后退出。子进程打印
计数器= 3
然后退出。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句