我正在编写一个伪 shell 程序,它从父进程创建一个子进程。父进程等待子进程完成后再继续。我的 fork 代码如下所示:
if(fork()==0)
{
execvp(cmd, args);
}
else
{
int status = 0;
wait(&status);
printf("Child exited with status of %d\n", status);
}
但是,我希望能够解析“&”运算符,这样如果用户在命令行末尾输入它,则父级不会在提示用户输入另一个命令之前等待子级。我添加了一些代码来处理这个问题,但我不确定它是否正常工作。它看起来像:
if(fork()==0)
{
execvp(cmd, args);
}
else
{
if(andOp = 1) //boolean to keep track of if '&' was encountered in parsing
{
shellFunc(); //main function to prompt user for a cmd line
}
int status = 0;
wait(&status);
printf("Child exited with status of %d\n", status);
}
这真的能达到常规 shell 所达到的并发性吗?
最佳答案
注意赋值而不是比较。
谨防执行命令失败 - execvp()
之后的 exit(1);
。
我想我会使用:
if (andOp == 0)
{
int status;
int corpse = wait(&status);
printf("Child %d exited with status 0x%04X\n", corpse, status);
}
也就是说,如果“&”丢失,我只会等待。
但是,由于后台子进程随机死亡,您需要跟踪后台进程,特别是,您需要在 wait()
上循环,直到您刚刚 fork 的子进程死亡。因此,您还需要从 fork()
捕获该 PID。
您可能想在收集您正在等待的子进程后使用 waitpid()
来清理任何其他主体,使用非阻塞选项,以便如果没有这样的子进程 children ,它立即返回。您仍然会在循环中使用它,这样如果 6 个后台作业全部完成,您就可以将它们全部收集起来。
或者,您可以考虑忽略“子进程死亡”(SIGCHLD) 信号 - 并让系统处理它们。但是,shell 通常会报告后台作业之一何时完成。
关于C-伪shell和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3920978/