Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 子进程在运行fork()时接管父进程_C_Process_Fork_Execvp_Waitpid - Fatal编程技术网

C 子进程在运行fork()时接管父进程

C 子进程在运行fork()时接管父进程,c,process,fork,execvp,waitpid,C,Process,Fork,Execvp,Waitpid,我有一个问题,我试图通过execvp()运行多个命令。为此,我有一个while循环来遍历每个命令,解析它,然后调用一个函数来使用fork+exec 问题是,我将运行fork+exec,当我等待exec通过时,父级运行并继续执行第二个循环,即第二个命令。但根据我的理解,发生的是前一个循环中的子进程接管,突然,子进程就是当前进程 如何在子进程中运行进程,但在父进程中保持控制?我在上面看到的所有示例都是针对父进程的,它们在继续之前等待子进程终止,但在本任务中我没有选择权-我应该让子进程保持运行,稍后检

我有一个问题,我试图通过execvp()运行多个命令。为此,我有一个while循环来遍历每个命令,解析它,然后调用一个函数来使用fork+exec

问题是,我将运行fork+exec,当我等待exec通过时,父级运行并继续执行第二个循环,即第二个命令。但根据我的理解,发生的是前一个循环中的子进程接管,突然,子进程就是当前进程

如何在子进程中运行进程,但在父进程中保持控制?我在上面看到的所有示例都是针对父进程的,它们在继续之前等待子进程终止,但在本任务中我没有选择权-我应该让子进程保持运行,稍后检查它们是否仍在运行

以下是我思考过程中的一些伪代码:

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

您需要确保只在子对象中调用
exec
,而不是在父对象中调用。当
fork()
返回时,它会执行两次(一次在子对象中,一次在父对象中),并返回以下内容:

  • 如果我们在父对象中,则为非零(子对象的PID)。我们可以使用此PID来等待子级终止使用
  • 如果我们在孩子身上,那就零
  • 如果fork失败,则为负值(在这种情况下,它只在父进程中返回一次,因为无法创建子进程)

您可能想考虑使用以下结构:

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(...);
}
intpid=fork();
if(pid<0){
perror(“fork”);//记住要检查错误!
}否则如果(pid==0){
//我们是在孩子身上
// ...
if(execvp(…)<0){
perror(“执行董事”);
}
}否则{
//我们在父节点中;如果需要,等待子节点使用waitpid终止。
waitpid(…);
}
为了简单起见,我在这里包括了
waitpid
调用;由于分配要求您保持子进程运行,因此您可以稍后使用该函数或通过处理
SIGCHLD
来检查其状态

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;
}
int main(int argc,char**argv){
int*status=malloc(sizeof(int)*(argc-1));
int i=0;
while((waitpid(fork(),&status[i++],0))==-1)| | i
谢谢您的回答!不过我在代码中已经这样做了-我使用了
waitpid()
WNOHANG
选项,因此我不必等待子进程。据我所知,子进程不会终止。在这种情况下该如何工作?@B.M.Corwen如果没有子进程退出,并且您调用
waitpid(0,&status,WNOHANG)
,它将立即返回零(与子进程确实终止时的子进程PID相反):。我认为尝试将fork+exec与等待孩子的步骤结合起来可能会产生一些混乱;根据你的描述,问题更多的是前者而不是后者。对不起,我还是不太明白。在我调用fork的函数中,我实际上已经按照上面的建议构建了我的代码,我仍然遇到了子进程接管的问题。虽然控件最终会返回到父级,但是存在一个延迟,在这个延迟中,exec似乎直到下一个循环才运行,而我应该在下一个循环中测试下一个命令。是否有办法管理此问题?Exec也可能失败
如何在子进程中运行进程,但在父进程中保持控制?
。这是什么意思?你说的“控制”是什么意思?您是否正在尝试确保父级不会产生处理器?您是否试图确保在创建所有子项之前,第一个子项不会开始执行?您是否试图确保所有子进程都按特定顺序运行?您所说的“当前进程”是什么意思?如果您有多个处理器,并且多个子进程正在运行并将数据写入您的tty…那么您将获得交错输出。听起来你在寻找一种同步机制。在
fork()
调用中,我尝试在子进程中调用
exec()
exec()
是我尝试运行的命令(例如
ls a
)。但是,我只想运行
exec()
,然后返回父进程,继续运行更多子进程以获得更多命令。同时,子进程只是在后台继续运行。希望这是有意义的,我在解释它时遇到了困难。在调用fork之后,父级和子级将同时运行。如果子执行'ls',则它会将输出写入其标准输出,这可能是调用程序的终端。父级仍在运行(除非它因某种原因退出),并生成更多的子级。仅仅因为孩子正在向tty写入输出并不意味着它已经“接管”了。你说的话中的某些东西让某些东西咔嗒咔嗒响,所以我回去修复了一些东西。现在我能看到你所指的行为了。现在的问题似乎是,在
while
循环的第一次运行中,它似乎只通过父代码时钟。直到第二次运行
while
循环(应该是第二个命令),第一次运行的子进程才开始运行。有没有办法解决这个滞后问题?