我试图在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
希望我很清楚。如果有任何疑问,请提出问题
答案 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()
的第一个参数。