父进程创建指定数量的子进程,并且子进程不再创建子进程的写法

网上很多父进程创建指定数目的子进程的方法,但是我发现很多都是很简单粗暴,只考虑了父进程创建子进程,没考虑子进程还会创建子进程,子进程的子进程还会创建子进程……

这里,我们先看看网上大部分的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
for (int i = 0; i < 4; i++) {
fork();
}

sleep(-1);

return 0;
}

编译后运行代码:

1
2
gcc fork.c -o fork
./fork

另外开启一个终端,然后查看进程个数:

1
ps aux | grep fork

显示结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
67521 root      0:03 ./fork
67522 root 0:03 ./fork
67523 root 0:03 ./fork
67524 root 0:03 ./fork
67525 root 0:03 ./fork
67526 root 0:03 ./fork
67527 root 0:03 ./fork
67528 root 0:03 ./fork
67529 root 0:03 ./fork
67530 root 0:03 ./fork
67531 root 0:03 ./fork
67532 root 0:03 ./fork
67533 root 0:03 ./fork
67534 root 0:03 ./fork
67535 root 0:03 ./fork
67536 root 0:03 ./fork

我们发现,这里实际上是有16个进程的,除去进程id为67521的这个最祖先进程,后面的都是多出来的。我们再看看进程树:

1
pstree -p 67521

结果如下:

1
2
3
4
5
6
7
8
fork(67521)-+-fork(67522)-+-fork(67526)-+-fork(67532)---fork(67534)
| | `-fork(67533)
| |-fork(67527)---fork(67536)
| `-fork(67528)
|-fork(67523)-+-fork(67530)---fork(67535)
| `-fork(67531)
|-fork(67524)---fork(67529)
`-fork(67525)

可以很清晰的看出进程之间的关系和fork了多少次。

那么,正确的写法应该是什么样子的呢?我这里给出两种写法。

写法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
pid_t ppid;

ppid = getpid();

for (int i = 0; i < 4; i++) {
if (getpid() == ppid) {
fork();
}
}

sleep(-1);

return 0;
}

查看进程情况:

1
ps aux | grep fork

结果如下:

1
2
3
4
5
70599 root      0:00 ./fork
70600 root 0:00 ./fork
70601 root 0:00 ./fork
70602 root 0:00 ./fork
70603 root 0:00 ./fork

查看进程树:

1
pstree -p 70599

结果如下:

1
2
3
4
fork(70599)-+-fork(70600)
|-fork(70601)
|-fork(70602)
`-fork(70603)

可以看出,确实是只创建了四个子进程,并且子进程没有再创建子进程。

写法二:

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
#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h>

int Fork();

int main(int argc, char const *argv[])
{
pid_t ppid;

ppid = getpid();

for (int i = 0; i < 4; i++) {
Fork();
}

// parent process

sleep(-1);

return 0;
}

int Fork()
{
pid_t pid;

pid = fork();
if (pid > 0) {
return pid;
}

// child process

for (;;) {
// some code
}
}

查看进程情况:

1
ps aux | grep fork

结果如下:

1
2
3
4
5
74107 root      0:00 ./fork
74108 root 0:01 ./fork
74109 root 0:01 ./fork
74110 root 0:01 ./fork
74111 root 0:01 ./fork

创建进程树:

1
pstree -p 74107

结果如下:

1
2
3
4
fork(74107)-+-fork(74108)
|-fork(74109)
|-fork(74110)
`-fork(74111)