Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 停止一个进程,然后在不终止它的情况下再次使用它_C_Process - Fatal编程技术网

C 停止一个进程,然后在不终止它的情况下再次使用它

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”);

在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);
      }
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语言中,没有机制提供从一开始就重新启动的功能。除此之外,该过程可能有副作用(例如,更改的文件),因此,即使您以某种方式重新启动它,它运行的世界也与它最初启动时的世界不同。我将提供一个示例代码,使其更易于理解我的问题。进程无法从一开始就真正重新启动。您可以在新进程中重新运行同一程序。或者,如果您有控制在子进程中运行的程序(如中所述,您可以修改它),然后您可以实现一些方法来发出信号,使其行为看起来像是重新启动的,但是对于任意程序,没有获得这种结果的机制。尽管您的代码存在其他问题,您希望终止的进程如何打印任何内容?打个残酷的比方,如果你已经杀了一个人,你不希望他们在你第二次开枪时尖叫吗?