Linux系统下,fork()函数是用作创建进程的,注意了:不是创建线程。至于线程和进程的区别,简单提下:
1、线程包含在进程内部,一个进程可以同时进行多个线程;
2、一个进程是一项可执行的程序;
3、线程是执行命令的最小单位;
4、一个进程可以创建多个子进程。
这里就Linux系统下的进程创建,作出解释。
代码1:
-
#include<stdio.h>
-
-
int main(void)
-
{
-
printf("fork.\n");
-
int pid = 0;
-
pid = fork();
-
if (pid == 0) {
-
printf("child=%d.\n", getpid());
-
return -1;
-
}
-
printf("father=%d.\n", getpid());
-
return 0;
-
}
代码执行之后:
-
one@one-Rev-1-0:~/programming/fork$ ./forks
-
fork.
-
father=7454.
-
child=7455.
注意到,输出的结果中有父子进程的共同输出。
fork()进程创建之后,父进程中的pid=0首先被返回【1】
这个时候,父进程已经在12行执行,pid=0 进入的是子进程,然而子进程在return -1是返回【2】
这些都与操作系统的调度有关:操作系统将fork()函数的返回值保存到自身数据空间,然而子进程将在pid=0出分叉。
代码2:
-
#include<stdio.h>
-
-
int main(void)
-
{
-
printf("fork.\n");
-
int pid = 0;
-
pid = fork();
-
if (pid == 0) {
-
printf("child=%d.\n", getpid());
-
}
-
printf("father=%d.\n", getpid());
-
return 0;
-
}
这个代码只是将上面的代码1的第10行删除。
执行结果如下:
-
one@one-Rev-1-0:~/programming/fork$ ./forks
-
fork.
-
father=7682.
-
child=7683.
-
father=7683.
这个输出中,可以证明到:
子进程只是将父进程的代码在fork()之后复制了一份【3】
fork()之后,父进程继续执行,这个时候,通过getpid()函数得到的是子进程的pid【4】
注意到pid=0是父进程的id[5]
现在来总结一下前面5点:
在Linux系统中,通过fork()之后的程序,创建一个子进程。返回的进程id号保存在父进程中,子进程可以通过getpid()来获取自己的pid。子进程共享父进程代码,但是不共享数据空间。当fork()完成之后,父进程继续执行。子进程可以执行父进程的代码。
如果说基本理解了,那么现在看一下下面这个代码:
-
#include<stdio.h>
-
-
int main(void)
-
{
-
int pid = 0;
-
int i;
-
for (i = 0; i < 3; i++) {
-
-
pid = fork();
-
printf("*");
-
}
-
-
return 0;
-
-
}
这个代码很简单就是一个循环,里面创建子进程,并且输出结果。
那么这个输出结果是?
a、8 b、16 c、24 d、30
答案是24个星花(*)。
先看一下输出结果:
-
one@one-Rev-1-0:~/programming/fork$ cat 2fork.txt
-
pid=8895*
-
pid=8895*
-
pid=8895*
-
pid=8895*
-
pid=8895*
-
pid=8898*
-
pid=8895*
-
pid=8897*
-
pid=8897*
-
pid=8895*
-
pid=8897*
-
pid=8899*
-
pid=8896*
-
pid=8896*
-
pid=8896*
-
pid=8896*
-
pid=8896*
-
pid=8901*
-
pid=8896*
-
pid=8900*
-
pid=8900*
-
pid=8896*
-
pid=8900*
-
pid=8902*
现在统计一下:
8895:7
8896:7
8897:3
8898:1
8899:1
8900:3
8901:1
8902:1
总计:24.
这个怎么来的?
其实这样撇开来看:
【1】父进程先执行3次,注意了,操作系统中是以堆栈的形式存储的。
【2】最先返回的是i=2是父进程创建的子进程。
【3】注意了,在父进程执行3次的过程中,父进程是直接输出的,但是父进程创建的子进程是保存在堆栈中,也就是说,父进程在i=2的时候,将最后有父进程创建的子进程压到堆栈中,此时堆栈保存的是两个父进程的id。
【4】当最后一个有父进程创建的子进程输出完毕之后,就是i=1时由父进程创建的子进程。
【5】i=1是父进程创建了一个【11】子进程,别且该子进程自己也创建了【12】子进程。所以为了保存【12】子进程的id必须要保存父进程id号和【11】子进程的id号,这就导致了上面怪异的输出结果。对于其他的子进程,推断类似。
说白了,主要还是要理解:
【1】fork一下,返回两下
【2】存储数据,需要堆栈[,输出的时候,不一定按照堆栈输出的,可能中间有查找工作,这个时候,就有可能打乱输出结果]
好了,就这些吧。
阅读(5493) | 评论(0) | 转发(0) |