Ok so I have been trying to learn to master child processes and properly waiting for them to finish. I have read a lot of Stack Overflow Q/A and I still can't seem to get this to work as I want it to. I have been reading/searching through the book (C++ Primer plus 6th ed.) - I have done some research and still I can't make it wait as I wanted to.

So I have looked at several things here on Stack Overflow for reference: Checking the status of a child process in C++

Here is what I have tried so far:

using namespace std;
int main() {
int status;
pid_t child;
child = fork();

if ( child > 0 ) {
    cout << "\nChild #1 is in charge\n";
    execlp("ls", "ls", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething wen't wrong in the forking process\n";
}

else {

}

child = fork();
if ( child > 0 ) {
    cout << "\nSecond child is in charge\n";
    execlp("locate", "locate", "etc", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething went wrong in the forking of second child!\n";
}

else {

}

Now this would show Child #1 is in charge and Second child is in charge then it would mix the two commands (I see some ls in between locate etc).

Second thing I have tried:

using namespace std;
int main() {
int status;
pid_t child;
pid_t ch_status = waitpid(child, &status, WNOHANG);

child = fork();
if ( child > 0 ) {
    cout << "\nChild is in charge\n";
    execlp("ls", "ls", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething wen't wrong in the forking process\n";
}

if ( ch_status == 0 ) {

}

else if ( ch_status == -1 ) {
    cout << "\nERROR IN CHILD #1\n";
}

else {

}

child = fork();
if ( child == 0 ) {
    cout << "\nSecond child is in charge\n";
    execlp("locate", "locate", "etc", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething went wrong in the forking of second child!\n";
}

if ( ch_status == 0 ) {

}

else if ( ch_status == -1 ) {
    cout << "\nERROR IN CHILD #1\n";
}

else {

}

child = fork();
if ( child > 0 ) {
    cout << "\nThird child is in charge!\n";
    execlp("echo", "echo", "herro", NULL);
}

else if ( child < 0 ) {
    cout << "\nForking of third child failed!\n";
}

if ( ch_status == 0 ) {

}

else if ( ch_status == -1 ) {
    cout << "\nERROR IN CHILD #2\n";
}

else {

}

return 0;
}

This is more based on the link which I provided, it yielded the same result as the first test run I did, except it would also show ERROR IN CHILD #1/2.

The commands are irrelevant, I just wan't to understand what I am doing wrong here... I have also tried nesting them in else { //start second fork here }, but I got nowhere with this either.

From what I understand after reading the waitpid(2) manual I should be using WNOHANG; http://linux.die.net/man/2/waitpid

Any suggestions/pointers are greatly appreciated.

If possible, please submit a sample code of how you would accomplish the correct result (execute command 1 -> wait until done -> execute command 2 -> exit).

Look forward to replies.

有帮助吗?

解决方案

You should be calling waitpid() in the parent after you fork. That is, it should go into the child > 0 branch.

The function's purpose is to "wait for a change in the child state." However, you're calling it before you spawn a child.

The code should then look like this:

using namespace std;
int main() {

int status;
pid_t child;

child = fork();
if ( child == 0 ) {
    cout << "\nChild is in charge" << endl;
    execlp("ls", "ls", NULL);
} else if ( child < 0 ) {
    cout << "\nSomething wen't wrong in the forking process" << endl;
} else {
    cout << "Parent waiting" << endl;
    pid_t ch_status = waitpid(child, &status, WNOHANG);
    if (ch_status == -1) {
      cout << "\nERROR IN CHILD #1" << endl;
    }
}

child = fork();
//same procedure as above

}

其他提示

You are incorrectly judging the order in which output statements executed based on the order their output was flushed. While output can't be flushed until the corresponding statement is executed, you have no flush calls in your code. So flushing can happen much later.

Use endl instead of putting a \n at the end of your lines. The endl manipulator includes a flush.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top