forking a process

Discussion in 'C Programming' started by felixfix@gmail.com, Sep 18, 2005.

  1. Guest

    Hi all,

    I am just wondering if something is wrong with my program. What it
    bascially does is to output a fibonacci sequence base on the
    command-line output. If I give a 5, it will generate the first 5
    fibonacci number. The problem is, I thought the parent process will
    always go first, and so here I should get "0, 1, 1, 2, 3" But I ran the

    program, it will give me "1, 2, 3, 0, 1", which is, the child process
    ran first. Is there any way to make the parent goes first?

    Thanks.
    fix.

    #include <sys/types.h>
    #include <stdio.h>
    #include <unistd.h>

    int main(int argc, char *argv[])
    {
    int param;
    pid_t pid;
    int i;
    int fib_n_2 = 0;
    int fib_n_1 = 1;
    int fib_n;

    if (argc != 2)
    {
    fprintf(stderr, "An integer parameter is required\n");
    exit(-1);
    }

    param = atoi(argv[1]);

    if (param < 0)
    {
    fprintf(stderr, "An integer > 0 is required\n");
    exit(-1);
    }

    pid = fork();

    if (pid < 0) {
    fprintf(stderr, "Fork Failed\n");
    exit(-1);
    }
    else if (pid > 0) { /* Parent process */
    switch(param)
    {
    case 0:
    printf("0\n");
    break;
    case 1:
    printf("0, 1\n");
    break;
    default:
    printf("0, 1, ");
    }
    wait(NULL);

    printf("end Fibonacci sequence...\n");
    exit(0);
    }
    else if (pid == 0) { /* Child process */

    /* HERE */
    for (i = 2; i < param; i++)
    {
    fib_n = fib_n_1 + fib_n_2;
    fib_n_2 = fib_n_1;
    fib_n_1 = fib_n;
    printf("%d, ", fib_n);
    }
    }
    }
    , Sep 18, 2005
    #1
    1. Advertising

  2. writes:
    > I am just wondering if something is wrong with my program. What it
    > bascially does is to output a fibonacci sequence base on the
    > command-line output. If I give a 5, it will generate the first 5
    > fibonacci number. The problem is, I thought the parent process will
    > always go first, and so here I should get "0, 1, 1, 2, 3" But I ran the
    >
    > program, it will give me "1, 2, 3, 0, 1", which is, the child process
    > ran first. Is there any way to make the parent goes first?


    fork() is not standard C. Try comp.unix.programmer.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Sep 18, 2005
    #2
    1. Advertising

  3. In article <>,
    <> wrote:
    >I am just wondering if something is wrong with my program. What it
    >bascially does is to output a fibonacci sequence base on the
    >command-line output. If I give a 5, it will generate the first 5
    >fibonacci number. The problem is, I thought the parent process will
    >always go first, and so here I should get "0, 1, 1, 2, 3" But I ran the
    >program, it will give me "1, 2, 3, 0, 1", which is, the child process
    >ran first. Is there any way to make the parent goes first?


    C does not define any notion of "process", so whether you can
    force a particular process to "go first" or not is out of the scope
    of this newsgroup. comp.unix.programming might perhaps be more
    appropriate.


    [OT]

    >#include <sys/types.h>
    >#include <stdio.h>
    >#include <unistd.h>
    >
    >int main(int argc, char *argv[])
    >{
    > int param;
    > pid_t pid;
    > int i;
    > int fib_n_2 = 0;
    > int fib_n_1 = 1;
    > int fib_n;
    >
    > if (argc != 2)
    > {
    > fprintf(stderr, "An integer parameter is required\n");
    > exit(-1);
    > }
    >
    > param = atoi(argv[1]);
    >
    > if (param < 0)
    > {
    > fprintf(stderr, "An integer > 0 is required\n");
    > exit(-1);
    > }
    >
    > pid = fork();
    >
    > if (pid < 0) {
    > fprintf(stderr, "Fork Failed\n");
    > exit(-1);
    > }
    > else if (pid > 0) { /* Parent process */
    > switch(param)
    > {
    > case 0:
    > printf("0\n");
    > break;
    > case 1:
    > printf("0, 1\n");
    > break;
    > default:
    > printf("0, 1, ");
    > }
    > wait(NULL);
    >
    > printf("end Fibonacci sequence...\n");
    > exit(0);
    > }
    > else if (pid == 0) { /* Child process */
    >
    > /* HERE */
    > for (i = 2; i < param; i++)
    > {
    > fib_n = fib_n_1 + fib_n_2;
    > fib_n_2 = fib_n_1;
    > fib_n_1 = fib_n;
    > printf("%d, ", fib_n);
    > }
    > }
    >}


    You need to create a synchronization method between the two
    processes, so that the child process knows when it is safe to
    proceed. There are a number of different methods you can use,
    including (but not limited to):

    - a semaphore

    - a POSIX Threads mutex

    - creating a pipe() before forking, with the child waiting
    with "blocking I/O" (to read input from the pipe, and with the
    parent not writing to the pipe until it is safe for the child
    to proceed. [Note: do not use buffered I/O for this, unless
    the parent process specifically flushes the I/O stream.]

    - setting up a signal handler in the child process, put the
    child process to sleep, then when the parent process is ready,
    have it sigqueue() to send a signal to the child process to wake
    the child up. However, proper operation of this depends on the
    parent waiting long enough for the child to establish the signal
    handler, which is tricky because the child is not certain to run
    within any particular length of time. So you might have to
    establish the signal handler -before- forking, and then rely
    upon signal inheritence. Unfortunately, native signal inheritence
    differs between System V and BSD derived Unixes, so for portability
    you need to use the POSIX signal handling layer (e.g., sigaction(),
    sigqueue() -- *not* kill() !)

    - create and initialize a volatile variable before the fork(). In the
    child, go into a loop of waiting and then testing to see whether
    the volatile variable is still the initial value, looping back to
    wait more if it is. In the parent, once the parent processing is
    complete, and before the wait() or waitpid(), set the volatile
    variable to the alternate value.


    These methods all have a common flaw, which is that none of them
    can force the underlying operating system to run the code for
    the parent process. The operating system might decide for some reason
    to wait around for the child to "do something" before allowing
    the parent to proceed, so the output from the parent could in theory
    end up postponed rather some time. This is not particularily likely
    on a Unix system, but you do not have any control over the
    scheduling algorithm between processes. You might, for that reason,
    choose to use POSIX Threads instead -- since threads are part of the
    same process, you do have some relative scheduling control.
    But proper bug-free implementations of POSIX threads are relatively
    uncommon compared to fork()...
    --
    "This was a Golden Age, a time of high adventure, rich living and
    hard dying... but nobody thought so." -- Alfred Bester, TSMD
    Walter Roberson, Sep 18, 2005
    #3
  4. SM Ryan Guest

    wrote:
    # Hi all,
    #
    # I am just wondering if something is wrong with my program. What it
    # bascially does is to output a fibonacci sequence base on the
    # command-line output. If I give a 5, it will generate the first 5
    # fibonacci number. The problem is, I thought the parent process will
    # always go first, and so here I should get "0, 1, 1, 2, 3" But I ran the
    #
    # program, it will give me "1, 2, 3, 0, 1", which is, the child process
    # ran first. Is there any way to make the parent goes first?

    Unless the system makes this guarentee explicitly, you should not
    presume it. Generally in parallel programming, you need to use
    explicit mechanisms to serialise parallel processes. Since C does
    not have these mechanisms built into the grammar of language
    (compared to, say, Concurrent Pascal), you need to use a library
    specific to your system to serialise.

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    Haven't you ever heard the customer is always right?
    SM Ryan, Sep 18, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roy Smith

    Forking sub-process in CppUnit?

    Roy Smith, Jul 4, 2003, in forum: C++
    Replies:
    0
    Views:
    376
    Roy Smith
    Jul 4, 2003
  2. Andrew Robert

    Process forking on Windows

    Andrew Robert, May 17, 2006, in forum: Python
    Replies:
    9
    Views:
    2,172
    Benji York
    May 19, 2006
  3. Jan Koprowski
    Replies:
    0
    Views:
    532
    Jan Koprowski
    Jan 26, 2009
  4. John Connor
    Replies:
    0
    Views:
    225
    John Connor
    Apr 8, 2011
  5. Heiko Wundram
    Replies:
    3
    Views:
    500
Loading...

Share This Page