fork() problem

Hi can someone help me please with multiple fork problem. I have problem with creating processes going child by child...It means I create one child after it a create another child ... etc.
Somethint like this scheme:
------- ------- -------- --------
|child_1 | ->|child_2| ->|child_3 | -> | child_100|
-------- ------- -------- ........ --------

Here is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


void Fork_Children (int N_Children)
{
    int i;
	int pid;
    for (i = 1; i <= N_Children; i++) 
	{
        pid = fork();
       
        if (pid == 0) 
		{
            printf("I am a child: %d PID: %d\n",i, getpid());
			         
			return;
        }
    }
}

int main (int argc, char *argv[]) 
{
    Fork_Children(atoi(argv[1]));
    return 0;
}


and I was expecting this on output:

I am a child: 1 PID: 1215
I am a child: 2 PID: 1216
I am a child: 3 PID: 1217
I am a child: 4 PID: 1218
I am a child: 5 PID: 1219
I am a child: 6 PID: 1215
I am a child: 7 PID: 1216
I am a child: 8 PID: 1217
I am a child: 9 PID: 1218
I am a child: 10 PID: 1219
I am a child: 11 PID: 1215
I am a child: 12 PID: 1216
I am a child: 13 PID: 1217
I am a child: 14 PID: 1218
I am a child: 15 PID: 1219
I am a child: 16 PID: 1215
I am a child: 17 PID: 1216
I am a child: 18 PID: 1217
I am a child: 19 PID: 1218
I am a child: 20 PID: 1219

But i get this:

I am a child: 1 PID: 1950
I am a child: 2 PID: 1951
I am a child: 3 PID: 1952
I am a child: 4 PID: 1953
I am a child: 5 PID: 1954
I am a child: 6 PID: 1955
I am a child: 7 PID: 1956
I am a child: 8 PID: 1957
I am a child: 9 PID: 1958
I am a child: 10 PID: 1959
I am a child: 11 PID: 1960
I am a child: 12 PID: 1961
I am a child: 13 PID: 1962
I am a child: 14 PID: 1963
I am a child: 15 PID: 1964
@ubuntu:~$ I am a child: 16 PID: 1965
I am a child: 17 PID: 1966
I am a child: 20 PID: 1969
I am a child: 18 PID: 1967
I am a child: 19 PID: 1968


thank you for your help in advance.
You need to break out of the loop for the parent process (if pid > 0).
It looks to me like your child processes are all children of the parent (rather than the scheme you have outlined)

The return of the command prompt (did you run it with an & to background the process) and the out of order numbering are to be expected - they are independent processes.
I have solved it with wait(NULL). But now I have no idea how to put pipes into it. I mean the first child generate for example random number and send it via pipe to another children and to the last child. I was thinking about to use 2d array pipe (int pipe[Number_of_children][2]), but I don't know how to put it into the for loop..

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main (int argc, char *argv[])
{
int i;
int pid;
for (i = 1; i <= atoi(argv[1]); i++)
{
pid = fork();
wait(NULL);
if (pid == 0)
{

printf("I am a child: %d PID: %d\n",i, getpid());

return 0;
}
}
}
It would be impossible, as you are wating for your child to die before creating its brother. I dare you to visualize it
So can you please help me, how can I change this code to that one child creates his child, then his grandchild..etc, using for loop? Because, I've tried it different ways, but everytime it didn't work.
You are breaking the loop when you are a child.
Instead, break when you are the parent.

Now for the pipes I suppose that something like this could work (not tested)
1
2
3
4
5
6
7
8
9
10
11
12
int prev[2], next[2];
for (i = 1; i <= N_Children; i++){
  pipe( next );
  int pid = fork();
  if( pid>0 ){ //parent
    //...
    break;
  }
  //child code
  prev[0] = next[0]; //I've got a copy of the variables ¿right?
  prev[1] = next[1];
}
So you'll end with
$ ./a.bin | ./b.bin | c.bin | ...
When is this child creation going to end? Each child has no idea where it is in the sequence.

You could pass each child its number in the sequence as a command line argument when you launch the child.

The child process then increments the received argument and passes it on to the child it creates.

The 100th child will then know it is the 100th and not create its own child.

(No idea why you would want to do this)
It will end when i>N_Children (so N_Children are created)
IIRC when you do a fork() your children start with an exact copy of the memory and the registers.

So its next instruction will be the one after the fork (it has a copy of the PC), and its copy of 'i' keeps incrementing from where it left.
It was my school test on wednesday and I failed som I'm trying to solve this problem because next week I have correction option.

Here is the assignement:

Processes and Pipes

Your task is to create a program that creates 102 childs. Always two neighboring children will be connected with pipe, instead of the first child who will have pipe only for output. Also the last child have only pipe for input. All children will have standard inputs and outputs redirected to the pipe. First child generates children and sends via pipe to the second child, second child sends it to he third....etc...101 child receives the number and displays it on the screen.
Use dup.
Can you please tell me whats wrong with the 2d pipes? and if the forking is finally correct?

Desktop/fork3.cpp: In function ‘int main()’:
Desktop/fork3.cpp:12:21: error: invalid conversion from ‘int’ to ‘int*’
Desktop/fork3.cpp:12:21: error: initializing argument 1 of ‘int pipe(int*)’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h> 

int main()
{
int pipes[2];
pipe(pipes);
int pipes_2[100][2];
pipe(pipes_2[100][2]);

int child[100];

child[1] = fork();

if (child[1] == 0)
{
	close(pipes[0]);
	int number = 1000;	
	write(pipes[1], &number, sizeof(int));
	printf("I'm the first child, my PID is : %d\n", getpid());
	exit(0);
}
for(int i = 1; i < 100; i++)
{
if (child[i] != 0)
{
	child[i+1] = fork();
}
if (child[i] < 0)
{
	wait(NULL);
}
if (child[i] == 0)
{   
	close(pipes_2[i][0]);
	close(pipes_2[i + 1][1]);
	int number = 1000;
	printf("I'm the %d .and my PID is %d\n", i, getpid());
	write(pipes_2[i][1], &number, sizeof(int));
	break;
	exit(0);
}
}
return(0);
}
Please indent your code.
int pipe( int fildes[2] ); That's the prototype. Respect it.
As you are doing the pipe before any forking, all the children have the same file descriptors. That means that all are conected directly to the first process

Array index goes from 0 to n-1
It is the Kernel who decides which process to run next, not the user program. In fact, the child process has the same priority with the parent process, so it does not preempt the parent process. In your first program, 1967,1968,1969 may have been created long ago, the kernel schedules to decide which process to run next, it is possible that the kernel puts process 1969 to run first.
Refer to process scheduling in Linux kernel.
man fork
man wait
my result:
root@localhost:/home/James/tmp/test# ./a.out 10
I am a child: 1 PID: 7279
I am a child: 3 PID: 7281
I am a child: 6 PID: 7284
I am a child: 5 PID: 7283
I am a child: 9 PID: 7287
I am a child: 8 PID: 7286
I am a child: 10 PID: 7288
I am a child: 7 PID: 7285
I am a child: 4 PID: 7282
root@localhost:/home/James/tmp/test# I am a child: 2 PID: 7280
Topic archived. No new replies allowed.