-2

I have a program that should launch another process and work simultaneously with it. I am using fork() and system() to accomplish this. I have code verifying that that my system() call returns, but every time I execute I have to manually end the execution by typing ctrl c. I can tell that one of my processes terminates, but I am not quite sure which one. I believe it is the parent. Both should be caught by return statements though.

Here is the parent process code (forkWaitTest):

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

int main(void)
{
        pid_t childPID;
        int status;

        childPID = fork();
        if(childPID >=0)
        {
                if(childPID == 0)
                {
                        cout <<"I'm the fork child";
                        cout.flush();
                        status=system("child");
                        cout << "status = " << status;
                        //exit(0);
                        //cout << "Am I getting here?";
                }
                else{
                cout << "I am the parent and can keep doing things ";
                int y=1;
                int x=7;
                cout<< y+x << " ";
                }
        }
        return 0;
}

This is the child process that is called

#include <stdio.h>

int main(int argc, char *argv[] )
{

  printf("I am the child\n");
  return 0;
}

Here is my output:

-bash-4.2$ forkWaitTest
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child
status = 0
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
art3m1sm00n
  • 389
  • 6
  • 9
  • 19
  • How did you determine that something is "never terminating"? – T.C. Sep 20 '14 at 22:32
  • I have to push `ctrl c` to get it to end – art3m1sm00n Sep 20 '14 at 22:35
  • Your parent should be `wait()`ing for the child, though admittedly I can't immediately see why failure to do that would cause this behaviour. – abligh Sep 20 '14 at 22:42
  • I want the parent to be running simultaneously with the child process that `system` calls. Eventually I have to turn this into a client server program for my course. A requirement is that my client launch my server – art3m1sm00n Sep 20 '14 at 22:43

2 Answers2

3

Your parent DID terminate. Let's look at your output:

-bash-4.2$ forkWaitTest
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child
status = 0

Now let's look at that more closely, particularly this bit:

I'm the fork child-bash-4.2$

See, right in the middle, it says bash-4.2$. That's the command prompt after the parent terminates. Then the child runs and also exits, but you are confused as it prints after the bash prompt. Your ^C merely prints the next line.

To verify, press return a few times rather than ^C.

abligh
  • 24,573
  • 4
  • 47
  • 84
  • Oh wow. So its actually ending it just doesn't look like it? Wow, I feel dumb. THANKS! This is the first time I have ever dealt with multiple processes running at once – art3m1sm00n Sep 20 '14 at 22:52
1

Make sure your messages end with newlines (add << endl to the outputs, for example).

I see your bash prompt (the -bash-4.2$) mixed up with the other outputs, partly because you don't have newlines in the outputs, and partly because your code doesn't show any attempt to wait for children to die. This means that your process did die.

You could type: ls -l and the shell would execute that command because it is waiting for you to type something. When you interrupt it (the shell), it prompts again, but it would have taken your input even without the interrupt.


With a slightly modified version of the child:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
  printf("I am the walrus (%d)\n", (int)getpid());
  return 0;
}

and a slightly modified version of the parent:

#include <cstdlib>
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

int main(void)
{
    pid_t childPID;
    int status;

    childPID = fork();
    if (childPID >= 0)
    {
        if (childPID == 0)
        {
            cout << "I'm the forked child (" << getpid() << ")\n";
            cout.flush();
            status = system("child");
            cout << "status = " << status << endl;
            cout << "Am I getting here?\n";
            return 0;
        }
        else
        {
            cout << "I am the parent and can keep doing things ";
            int y = 1;
            int x = 7;
            cout << y + x << endl;
        }
    }
    int corpse;
    while ((corpse = wait(&status)) != -1)
        cout << "PID " << corpse << " exited with status " << status << endl;
    return 0;
}

and with a prompt Osiris JL:, an example of the output I get is:

Osiris JL: ./parent
I am the parent and can keep doing things 8
I'm the forked child (3192)
I am the walrus (3193)
status = 0
Am I getting here?
PID 3192 exited with status 0
Osiris JL:

Note that the 'child' program is run by a child of the parent process's own child (that's why the getpid() values are printed). And the wait() in a loop in the parent process ensures that the child has died before the parent dies. Given the structure of the child process, which uses the system() function, the grandchild process (running the partly misnamed child process) has exited before the child exits before the parent exits. Omit the wait() loop and the parent can easily exit before the child and grandchild do:

Osiris JL: ./parent
I am the parent and can keep doing things 8
I'm the forked child (3207)
Osiris JL: I am the walrus (3208)
status = 0
Am I getting here?
ls -ld parent* child*
-rwxr-xr-x  1 jleffler  staff  8784 Sep 20 15:57 child
-rw-r--r--  1 jleffler  staff   122 Sep 20 15:57 child.cpp
drwxr-xr-x  3 jleffler  staff   102 Sep 20 15:57 child.dSYM
-rwxr-xr-x  1 jleffler  staff  9808 Sep 20 16:02 parent
-rw-r--r--  1 jleffler  staff   858 Sep 20 16:02 parent.cpp
drwxr-xr-x  3 jleffler  staff   102 Sep 20 16:02 parent.dSYM
Osiris JL: 
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278