我在尝试通过execvp()运行多个命令时遇到问题。为此,我有一个while循环遍历每个命令,将其解析,然后调用一个函数以使用fork + exec。
问题是,我将运行fork + exec,并且在等待exec通过的同时,父级运行并继续进行第二个循环,即。第二个命令。但是据我所知,发生的是上一个循环中的子进程接管了,突然之间,子进程就是当前进程。
如何在子流程中运行流程,但在父流程中保持控制?我在SO上看到的所有示例都是针对父进程的,它等待子进程终止再继续,但是我在此分配中没有选择-我应该让子进程保持运行并在以后检查看看它们是否仍在运行。
这是我思考过程的一些伪代码:
funct forkprocess() {
//call fork
//call execvp within child process, let process run and return control to parent
//if execvp failed, kill child process
//return child pid
}
int main() {
while(not end of file containing list of commands) :
//parse command for execvp call
//call forkprocess() to run process
//if childpid is returned, report it and store pid
//else, report failure
}
}
我的输出接近以下内容:
\\parent PID is printed
\\any code outside the if-else ladder for fork is printed
\\it jumps back to main and prints any statements there
[jumps to next iteration in loop, ie. the next command]
\\child PID is printed
\\parent PID is printed
\\any code outside the if-else ladder for fork is printed
\\it jumps back to main and prints any statements there
\\child PID is printed
答案 0 :(得分:0)
您需要确保exec
仅在子级而不是父级中被调用。当fork()
返回时,它会两次(一次在孩子中,一次在父母中),然后返回以下values:
waitpid
终止。您可能要考虑使用以下结构:
int pid = fork();
if(pid < 0) {
perror("fork"); // remember to error check!
} else if (pid == 0) {
// We are in the child
// ...
if(execvp(...) < 0) {
perror("exec");
}
} else {
// We are in the parent; wait for the child to terminate using waitpid if desired.
waitpid(...);
}
为简单起见,我在此处包括waitpid
调用;由于您的分配要求您保持子进程的运行,因此以后可以使用该功能或处理SIGCHLD
来检查其状态。
答案 1 :(得分:0)
int main(int argc, char ** argv) {
int status;
if((waitpid(fork(), &status, 0)) == -1) {
execvp(...);
/* print error */
exit(1);
}
return 0;
}
感谢您提出问题,如果将fork直接传递给waitpid,则父级将等待,而子级将执行exec,这将在成功时退出线程或在失败时返回并继续打印错误并退出。 这对于一次执行多个功能确实很有帮助...
int main(int argc, char ** argv) {
int *status = malloc(sizeof(int) * (argc - 1));
int i = 0;
while(((waitpid(fork(), &status[i++], 0)) == -1) || i < argc) {
execvp(argv[i], &argv[i + 1]);
/* print error */
exit(1);
}
return 0;
}