Does the C execv() function terminate the child pr

2020-02-15 06:54发布

问题:

Heres a breakdown of my code.

I have a program that forks a child (and registers the child's pid in a file) and then does its own thing. The child becomes any program the programmer has dignified with argv. When the child is finished executing, it sends a signal (using SIGUSR1) back to the parent processes so the parent knows to remove the child from the file. The parent should stop a second, acknowledge the deleted entry by updating its table, and continue where it left off.

pid = fork();
switch(pid){
case -1:{
    exit(1);
}

case 0 :{
    (*table[numP-1]).pid = getpid(); //Global that stores pids
    add();                             //saves table into a text file 
    freeT(table);                  //Frees table 
    execv(argv[3], &argv[4]);          //Executes new program with argv 
    printf("finished execution\n");  
    del(getpid());                     //Erases pid from file 
    refreshReq();                      //Sends SIGUSR1 to parent
    return 0;
}
default:{
    ... //Does its own thing
}
}

The problem is that the after execv successfully starts and finishes (A printf statement before the return 0 lets me know), I do not see the rest of the commands in the switch statement being executed. I am wondering if the execv has like a ^C command in it which kills the child when it finishes and thus never finishes the rest of the commands. I looked into the man pages but did not find anything useful on the subject.

Thanks!

回答1:

execv replaces the current process with a new one. In order to spawn a new process, you can use e.g. system(), popen(), or a combination of fork() and exec()



回答2:

execv replaces the currently executing program with a different one. It doesn't restore the old program once that new program is done, hence it's documented "on success, execv does not return".

So, you should see your message "finished execution" if and only if execv fails.



回答3:

Other people have already explained what execv and similar functions do, and why the next line of code is never executed. The logical next question is, so how should the parent detect that the child is done?

In the simple cases where the parent should do absolutely nothing while the child is running, just use system instead of fork and exec.

Or if the parent will do something else before the child exits, these are the key points:

  • When the child exits, the parent will get SIGCHLD. The default handler for SIGCHLD is ignore. If you want to catch that signal, install a handler before calling fork.
  • After a child has exited, the parent should call waitpid to clean up the child and find out what its exit status was.
  • The parent can also call wait or waitpid in a blocking mode to wait until a child exits.
  • The parent can also call waitpid in a non-blocking mode to find out whether the child has exited yet.


回答4:

What did you expect to happen? This is what execv does. Please read the documentation which says:

The exec() family of functions replaces the current process image with a new process image.

Perhaps you were after system or something, to ask the environment to spawn a new process in addition to the current one. Or.. isn't that what you already achieved through fork? It's hard to see what you want to accomplish here.