简体   繁体   English

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

[英]Child process takes over parent process when running fork()

I have a problem where I am trying to run multiple commands through execvp().我有一个问题,我试图通过 execvp() 运行多个命令。 To do this, I have a while loop doing through each command, parsing it, then calling a function to use fork + exec.为此,我有一个 while 循环遍历每个命令,解析它,然后调用 function 来使用 fork + exec。

The issue is, I will run fork + exec, and while I wait for the exec to go through, the parent runs and continues on to the second loop, ie.问题是,我将运行 fork + exec,当我等待 exec 到 go 时,父进程运行并继续到第二个循环,即。 the second command.第二个命令。 But what happens, from my understanding, is the child process from the previous loop takes over and all of a sudden, the child process is the current process.但是,据我了解,发生的事情是上一个循环中的子进程接管,突然之间,子进程就是当前进程。

How do you run a process in the child process, but maintain control in the parent?如何在子进程中运行进程,但在父进程中保持控制? All the examples I've seen on SO have been for parent processes what wait for the child process to terminate before continuing, but I don't have a choice in this assignment - I'm supposed to keep the child processes running and check later to see if they're still running.我在 SO 上看到的所有示例都是父进程在继续之前等待子进程终止,但我在这个分配中没有选择 - 我应该让子进程保持运行并稍后检查看看他们是否还在运行。

Here's some pseudocode of my thought process:这是我思考过程的一些伪代码:

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
   }
}

My output has been close to the following:我的 output 已经接近以下:

\\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

You need to make sure that exec is only called in the child, not the parent.您需要确保exec仅在子项中调用,而不是在父项中调用。 When fork() returns, it does so twice (once in the child, once in the parent), and it returns the following values :fork()返回时,它会执行两次(一次在子级中,一次在父级中),并返回以下

  • non-zero (the PID of the child) if we are in the parent.如果我们在父节点中,则非零(子节点的 PID)。 We can use this PID to wait for the child to terminate using waitpid .我们可以使用这个 PID 来等待子进程使用waitpid终止。
  • zero if we are in the child.如果我们在孩子身上,则为零。
  • negative if the fork failed (in which case it only returns once, in the parent process, since a child process could not be created)如果分叉失败,则为负(在这种情况下,它只返回一次,在父进程中,因为无法创建子进程)

You may want to consider using the following structure:您可能需要考虑使用以下结构:

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(...);
}

I include the waitpid call here for simplicity;为简单起见,我在此处包含了waitpid调用; since your assignment requires you to keep the child processes running you can check their status later by using either that function, or by handling SIGCHLD .由于您的分配要求您保持子进程运行,您可以稍后使用 function 或处理SIGCHLD检查它们的状态。

int main(int argc, char ** argv) {
    int status;

    if((waitpid(fork(), &status, 0)) == -1) {
       execvp(...);
       /* print error */
       exit(1);
    }
    return 0;
}

Thanks for the question, if fork is passed straight into waitpid the parent will wait, meanwhile the child will execute exec, which will exit the thread on success or return on failure and continue to print the error and exit.感谢提问,如果fork直接传入waitpid,父进程会等待,同时子进程会执行exec,成功退出线程,失败返回,继续打印错误退出。 This is really helpful for executing multiple functions at once...这对于一次执行多个功能真的很有帮助......

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM