2011-03-02 94 views
1

继承人我的代码细目。C execv()函数是否终止子进程?

我有一个程序,分叉一个孩子(并在一个文件中注册孩子的PID),然后做它自己的事情。孩子成为程序员与argv端庄的任何程序。当孩子完成执行时,它发送一个信号(使用SIGUSR1)回到父进程,以便父进程知道从该文件中删除孩子。父母应该停下来,通过更新其表格来确认已删除的条目,并继续保留它的位置。

pid = fork(); 
switch(pid){ 
case -1:{ 
    exit(1); 
} 

case 0 :{ 
    (*table[numP-1]).pid = getpid(); //Global that stores pids 
    add();        //saves table into a text file 
    freeT(table);     //Frees table 
    execv(argv[3], &argv[4]);   //Executes new program with argv 
    printf("finished execution\n"); 
    del(getpid());      //Erases pid from file 
    refreshReq();      //Sends SIGUSR1 to parent 
    return 0; 
} 
default:{ 
    ... //Does its own thing 
} 
} 

的问题是,在后execv成功启动和完成(A printf语句之前返回0让我知道),我没有看到在switch语句中的命令的其余部分正在执行。我想知道execv是否有一个^ C命令,它会在完成时杀死孩子,从而永远不会完成剩下的命令。我查看了手册页,但没有发现任何有用的主题。

谢谢!

+1

解决一个完全不同的观点:可以编写table [numP-1] - > pid而不是(* table [numP-1])。pid – 2011-03-02 19:26:02

回答

2

execv 用当前进程替换当前进程。为了产生一个新的过程,你可以使用例如system()popen(),或fork()的组合和exec()

+0

ah ... kk。所以execv在完成之后终止孩子,并且孩子没有责任终止自己(只要新程序正确结束)。 Hrm ..我想我需要重新编码我的代码:( – 2011-03-02 19:39:55

+0

也请注意整个'SIGUSR1'是一个错误,子进程在终止时自然向父节点发送'SIGCHLD',然后希望父节点'等待'这个系统避免了试图自己做信号的丑陋的竞争条件。 – 2011-03-02 20:47:09

4

execv替换为不同的一个当前正在执行的程序。一旦新程序完成,它不会恢复旧程序,因此它被记录为“成功,execv不返回”。

因此,当且仅当execv失败时,您应该看到您的消息“已完成执行”。

0

你预计会发生什么?这是execv所做的。请阅读the documentation它说:

的EXEC()函数系列用一个新的进程映像替换当前的进程映像。

也许你system或东西后,问环境产生新的进程除了当前的一个。或者..是不是你已经通过fork获得了什么?很难看到你想在这里完成什么。

1

其他人已经解释了什么execv和类似的功能,以及为什么下一行代码永远不会执行。下一个合乎逻辑的问题是,父母应该如何检测孩子是否完成了?

在父母在孩子运行时应该什么都不做的简单情况下,只需使用system而不是forkexec即可。

或者,如果父母会做点别的孩子退出之前,这些都是关键点:

  • 当孩子退出时,家长会得到SIGCHLDSIGCHLD的默认处理程序被忽略。如果您想捕获该信号,请在致电fork之前安装处理程序。
  • 孩子退出后,家长应拨打电话waitpid清理孩子,并了解退出状态。
  • 家长也可以在阻止模式下拨打waitwaitpid等到孩子退出。
  • 家长也可以在非阻塞模式下致电waitpid以确定孩子是否已退出。