C编程语言中是否有任何方法可以停止子进程,然后再次从头开始调用它?我已经意识到,如果我使用SIGKILL然后再次调用子进程,则不会发生任何事情。
void handler {
printf(“entered handler”);
kill(getpid(),SIGKILL);
}
int main () {
pid_t child;
child=fork();
if (child<0) printf(“error”);
else if (child==0) {
signal(SIGINT,handler);
pause();
}
else {
kill(child,SIGINT);
kill(child,SIGINT);
}
这应该打印两次“ Entered Handler”,但不会打印两次。可能是因为它无法再次呼叫孩子。我能以某种方式纠正吗?
答案 0 :(得分:1)
这应该打印两次“ Entered Handler”,但不会打印两次。 可能是因为它无法再次呼叫孩子。
这里存在多个问题,但是通常无法将SIGINT
两次交付给同一进程不是其中之一。问题包括:
SIGKILL
传递给它正在运行的进程,从而使该进程立即终止。一旦终止,该过程将不再响应其他信号,因此没有理由期望孩子会两次打印“输入的处理程序”。SIGINT
安装处理程序的孩子与向其发送该信号的父母之间存在竞争状态。如果子级在为其安装处理程序之前接收到该信号,则该子级将终止而不产生 any 输出。pause()
中的子级阻塞与父级信令之间存在竞争状态。如果信号处理程序没有杀死孩子,那么孩子可能会在到达pause()
调用之前接收到两个信号,因此根本无法终止。pause()
的活动,并且如果它没有通过自己给SIGKILL
自杀而自杀,那么该信号应促使它解锁并从pause()
返回正常终止的路径。因此,在第二个信号的传递和孩子的正常终止之间也会出现竞争状况。printf()
函数不是异步信号安全的。从信号处理程序调用它会产生不确定的行为。sigaction()
来安装信号处理程序,而不要安装signal()
,因为signal()
的行为未明确说明并且在实践中会有所不同。 signal()
的唯一安全用途是将信号处置重置为其默认设置。我可以改正吗 某种方式?
kill()
调用。printf()
调用替换信号处理程序中的write()
调用。sigaction()
代替signal()
来安装处理程序。默认标志应适合您使用。SIGINT
(通过sigprocmask()
),以便最初将其在子对象中阻塞。sigsuspend()
代替pause()
。sigsuspend()
返回后向父母发送某种响应(可能是其自身的信号,或者是父母可以读取的对管道的写操作),并让父母等待该响应在发送第二个信号之前。sigsuspend()
来接收第二个信号。