我不明白以下代码:
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);
}
}
}
当父进程等待子进程终止时,子进程如何实际杀死父进程?
答案 0 :(得分:3)
首先请注意,kill()
系统调用有些名称错误,因为它是一个用于向进程发送信号的通用函数。杀死目标进程只是几种可能结果中的一种。
然而,更一般地说,信号处理是一种中断机制。可以通过接收信号来中断许多库函数,包括wait()
。控制传递给该信号的已注册处理程序(如果有),否则执行默认操作。之后,被中断的函数返回,通过其返回码和/或设置errno
来指示错误。
已编辑添加 :此外,您自己的代码可能会因收到信号而中断。如果效果不是终止进程,则执行将在信号处理程序正常退出时从其停止的位置恢复,或者如果处理程序通过调用longjmp()
退出,则执行将在其他位置恢复。 < / p>
此外,signal delivery 是由内核处理的异步机制。一个过程可以被阻止或以其他方式占用并仍然接收信号;事实上,这是他们的重点。每个进程都有一个等待处理的待处理信号队列;对于大多数进程,此队列几乎一直是空的,但除非您明确阻止信号,否则进程假定它不会接收任何信号(并且无论如何都无法阻止某些信号)也绝对不安全。
在您的特定代码中,主要过程首先将function1()
设置为信号USR1
的处理程序。它然后分叉,子进程将函数function2()
设置为其处理程序的信号USR1
(不会因此影响父级),向父级发送信号USR1
,并进入无限循环。
同时,父母为其子进程启动wait()
。这将通过接收信号而中断。在收到信号并且注册的处理程序运行后,等待将结束,wait()
返回-1并将errno
设置为EINTR
。处理程序执行的操作之一是向子项发送SIGUSR1
。
收到信号后,孩子的正常执行流程将被中断,以运行其处理程序function2()
。这会更新子的变量counter
副本,打印其值和exit()
s。
最终结果:
主要流程打印
counter = 1
然后退出。子进程打印
counter = 3
然后退出。