C 停止一个进程,然后在不终止它的情况下再次使用它
在C编程语言中,有没有办法停止一个子进程,然后再次调用它从头开始?我已经意识到,如果我使用SIGKILL,然后再次调用子进程,那么什么都不会发生C 停止一个进程,然后在不终止它的情况下再次使用它,c,process,C,Process,在C编程语言中,有没有办法停止一个子进程,然后再次调用它从头开始?我已经意识到,如果我使用SIGKILL,然后再次调用子进程,那么什么都不会发生 void handler { printf(“entered handler”); kill(getpid(),SIGKILL); } int main () { pid_t child; child=fork(); if (child<0) printf(“error”);
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);
}
void处理程序{
printf(“输入处理人”);
kill(getpid(),SIGKILL);
}
int main(){
pid_t儿童;
child=fork();
如果(儿童)
这应该打印两次“输入的处理程序”,但不会。
可能是因为它不能再叫child了
这里有几个问题,但通常无法向同一流程交付两次SIGINT
。这些问题包括:
- 信号处理程序将一个
SIGKILL
传递给它正在运行的进程,从而影响该进程的立即终止。一旦终止,该进程将不会响应进一步的信号,因此没有理由期望子进程将打印“输入的处理程序”两次
- 为
SIGINT
安装处理程序的子级与发送该信号的父级之间存在竞争条件。如果子级在为其安装处理程序之前收到该信号,则子级将终止,而不产生任何输出
- 子级接受的第一个信号与传递给它的第二个信号之间存在竞争条件。正常信号不排队,因此如果在第一个信号仍挂起时传递第二个信号,则第二个信号将丢失
pause()
中的子阻塞与父信号之间存在竞争条件。如果信号处理程序没有杀死子信号,则子信号可能在到达pause()
调用之前接收两个信号,因此根本无法终止
- 如果孩子在父母第一次发出信号之前在
pause()
中阻塞,并且如果孩子没有通过发送SIGKILL
自杀,则该信号应使其解除阻塞并从pause()返回
,在正常终止的路径上。因此,在第二个信号的传递和子节点的正常终止之间也会存在竞争条件
printf()
函数不是异步信号安全函数。从信号处理程序调用它会产生未定义的行为
- 您应该始终使用
sigaction()
来安装信号处理程序,而不是signal()
,因为signal()
的行为未指定,并且在实践中会有所不同。signal()
我可以用英语纠正这个问题吗
有办法吗
从信号处理程序中删除kill()
调用
将信号处理程序中的printf()
调用替换为相应的write()
调用
使用sigaction()
而不是signal()
安装处理程序。默认标志应适合您的使用
通过以下方法解决各种竞争条件:
在分叉之前,使父块SIGINT
(通过sigprocmask()
)在子块中首先被阻塞
让孩子使用带有适当信号掩码的sigsupspend()
,而不是pause()
让孩子在从sigssuspend()
返回后向家长发送某种响应(可能是孩子自己的信号,或者是对家长可以读取的管道的写入),让家长在发送第二个信号之前等待该响应
让子系统再次调用sigssuspend()
以接收第二个信号
不知道你的意思。如果fork exec进入一个子进程,让它运行一点,kill(pid,SIGKILL)
,然后再次fork exec它,然后它应该从一开始就再次运行。您可能希望包含更详细的信息,确切地解释您正在做什么、您期望什么以及实际发生了什么,因为目前我们只是在猜测发生了什么。SIGSTOP后跟SIGCONT将暂停该进程,然后让它继续运行它是在您停止它时发生的。但这不会从一开始就重新启动它。在正常的C语言中,没有机制提供从一开始就重新启动的功能。除此之外,该过程可能有副作用(例如,更改的文件),因此,即使您以某种方式重新启动它,它运行的世界也与它最初启动时的世界不同。我将提供一个示例代码,使其更易于理解我的问题。进程无法从一开始就真正重新启动。您可以在新进程中重新运行同一程序。或者,如果您有控制在子进程中运行的程序(如中所述,您可以修改它),然后您可以实现一些方法来发出信号,使其行为看起来像是重新启动的,但是对于任意程序,没有获得这种结果的机制。尽管您的代码存在其他问题,您希望终止的进程如何打印任何内容?打个残酷的比方,如果你已经杀了一个人,你不希望他们在你第二次开枪时尖叫吗?