有没有办法在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);
}
这应该打印两次“输入处理程序”,但它不会。可能是因为它无法再次召唤孩子。我可以用某种方式纠正这个问题吗?
这应该打印两次“输入处理程序”,但它不会。可能是因为它无法再次召唤孩子。
这里有几个问题,但一般无法将SIGINT
两次交付给同一个过程并不是其中之一。问题包括:
SIGKILL
传递给它运行的进程,从而影响该进程的立即终止。一旦终止,该过程将不会响应更多信号,因此没有理由期望孩子将两次打印“输入的处理程序”。SIGINT
处理程序的孩子和发送该信号的父母之间存在竞争条件。如果孩子在为它安装处理程序之前收到信号,那么孩子将终止而不产生任何输出。pause()
的孩子和父母信号之间存在竞争条件。如果信号处理程序没有杀死孩子,那么孩子有可能在到达pause()
呼叫之前接收两个信号,因此根本不能终止。pause()
中阻塞,并且如果它没有通过传递自己的SIGKILL
而自杀,那么该信号应该使其解锁并从pause()
返回,在终止的路径上一般。因此,在第二信号的传递和儿童的正常终止之间也存在竞争条件。printf()
函数不是异步信号安全的。从信号处理程序调用它会产生未定义的行为。sigaction()
安装信号处理程序,而不是signal()
,因为signal()
的行为是不明确的,并且在实践中有所不同。 signal()
唯一安全的用途是将信号的处置重置为默认值。我可以用某种方式纠正这个问题吗?
kill()
调用。printf()
调用替换信号处理程序中的write()
调用。sigaction()
而不是signal()
来安装处理程序。默认标志应该适合您的使用。SIGINT
(通过sigprocmask()
),这样它最初将被封锁在孩子身上。
让孩子使用sigsuspend()
,使用适当的信号掩码,而不是pause()
。
让孩子从sigsuspend()
返回之后向父母发送某种响应(可能是他自己的信号,或者是父母可以读取的管道的写入),并且在发送第二个信号之前让父母等待该响应。
让孩子第二次打电话给sigsuspend()
接收第二个信号。