后台进程在终止前捕获进程ID

时间:2013-09-14 17:30:34

标签: c shell unix

我试图在C中模拟背景和前台进程。如果有'&'那​​么这样做最终的符号,我避免在父进程中等待该子进程。我还存储了我在列表中执行的所有后台命令,并尝试在完成后从列表中删除它们。但是对于ls -l&输出立即显示,只需按Enter键即可终止该过程。如何捕获该进程ID并从列表中删除它是否与列表中的现有pid匹配。

pid = fork();
//Code to add pid into a list if it is a background process
//this is done by parent as pid is always 0 for child processes
if(pid == 0){
    if(proc_state=='&'){
        setsid();           
    }
        // logic for creating command
        int ret= execvp( subcomm[0], subcomm );
    // handling error
}

//Parent will execute this
//Child will never come here if execvp executed successfully

if(proc_sate != '&'){
        for(i=0; i < count_pipe+1; i++){            
            int ret = waitpid(0, &flag ,0);
        // Code to remove procid from list if 'ret' matches with existing procid in the list.
        }
}

//Here proc_state just determines whether it is background or foreground.It is just a character. count_pipe is just a 
//variable holding number of pipes
希望我很清楚。如果有任何疑问,请提出问题

1 个答案:

答案 0 :(得分:1)

通常情况下,您可以在以下循环中使用waitpid()

int status;
pid_t corpse;

while ((corpse = waitpid(0, &status, WNOHANG)) != -1)
{
    /* Process PID of child that died with given status */
    ...
}

这会收集所有已经死亡的孩子,但是当没有更多的尸体可以收集时会回来。选项0表示“我的过程组中的任何死孩子”;另一种选择-1意味着“任何死去的孩子”。在其他情况下,您可以指定一个特定的PID来查看该子项是否已经死亡,或者一个负数将指定进程组中PGID等于绝对值的任何子项。

WNOHANG的意思是“如果没有尸体死亡,不要等待孩子死亡”;使用0意味着“等到相应类别的孩子死亡”,但是当没有这样的孩子离开时,呼叫将返回。

如果过程组中有多个子项,则无法保证将返回尸体的顺序,就像无法保证子项将会死亡的顺序一样。

您的要求并不完全清楚。例如,您可以根据最后启动的管道是否在后台运行来选择waitpid()的最后一个参数。如果您之前在后台启动了一个进程,您几乎可以随时收集它的尸体(除非您正在等待另一个进程组,或者除了该背景PID之外的特定PID)。您可能会根据具体情况选择waitpid()的第一个参数。