forking a process

F

felixfix

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

Keith Thompson

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.
 
W

Walter Roberson

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()...
 
S

SM Ryan

(e-mail address removed) 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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top