父进程创建指定数量的子进程,并且子进程不再创建子进程的写法
网上很多父进程创建指定数目的子进程的方法,但是我发现很多都是很简单粗暴,只考虑了父进程创建子进程,没考虑子进程还会创建子进程,子进程的子进程还会创建子进程……
这里,我们先看看网上大部分的做法:
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 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 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 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 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(); }
sleep(-1); return 0; }
int Fork() { pid_t pid;
pid = fork(); if (pid > 0) { return pid; }
for (;;) { } }
|
查看进程情况:
结果如下:
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 2 3 4
| fork(74107)-+-fork(74108) |-fork(74109) |-fork(74110) `-fork(74111)
|