Linux下下C语语言言的的fork()子子进进程程函函数数用用法法及及相相关关问问题题解解析析
fork
fork()函数是linux下的一个系统调用,它的作用是产生一个子进程,子进程是当前进程的一个 本,它跟父进程有一样的虚存内
容,但也有一些不同点。
但是,值得注意的是,父进程调用fork()后,fork()返回的是生成的子进程 (如果能顺利生成的话)的ID。子进程执行的起点也
是代码中fork的位置,不同的是下面这段C语言代码展示了fork()函数的使用方法:
// myfork.c
#include
#include
int main(int argc, char **argv) {
while ( ) {
pid_t pid = fork();
if (pid > 0) {
// 主进程
sleep(5);
} else if (pid == 0) {
// 子进程
return 0;
} else {
fprintf(stderr, "fork error\n");
return 2;
}
}
}
调用fork()函数后,系统会将当前进程的绝大部分资源拷贝一份 (其中的copy-on-write技术这里不详述),该函数的返回值有三
种情况,分别是:
1.大于0 ,表示当前进程为父进程,返回值是子进程号;
2.等于0 ,表示当前进程是子进程;
3.小于0 (确切地说是等于-1),表示fork()调用失败。
看两个比较有意思的C语言题目。
第第一一题题::计算下面代码理论上总共打印了多少行:(网易2011笔试题)
#include
#include
#include
int main(){
int i;
for(i = 0; i<5; i++){
fork();
printf("%d\n",getpid());
fflush(stdout);
}
}
问题解答:
这道问题并不难,最快的想法就是2+4+8+16+32,因为第一层的printf会有两个进程打印,第二层会增加到4个,以此往下,就
得出62行。
但我这里打算采用另外一种方法,一种更加直观的方法,就是直接数出来,这样会避免大脑短路,而且对下一题目有帮助。
要直接数出来也很简单,只是有些繁琐,因为每循环一次,都会打印一行并且产生一个子进程,子进程又会继续循环打印并产生
新的进程。我们可以在草稿纸上画一棵树,画出每个进程的子进程以及循环次数,如果你眼力够好,脑子不容易乱,这种方法很
快会让你得到正确答案。但我恰好脑子不是能够保证清醒的人,画了三遍树得到的都是错误答案。
随后,我在纸上用了一种更简单的数据结构 队列进行计算,并且顺利得出了答案。我是这样计算的:
首先,主进程会循环5次,则我们将5压入到队列中:
queue =" 5 ";
sum = 0; //sum是总打印次数
主进程会循环5次,打印5行并且产生5个子进程,这5个子进程分别会打印5,4 ,3,2,1行,则我们将这5个数放入队列,并将
第一个5出队列加入到sum 中:
queue = " 5 4 3 2 ";
sum = sum + 5;
这样,我们再取队列首元素,即5,他会打印5行,并且生成4个子进程,子进程的分别会打印4 ,3,2,1行,我们把这4个数放
入到队列中,并将第一个5出队列加入到sum 中:
queue = " 4 3 2 4 3 2 ";
sum = sum + 5;
我们继续重复上面的工作,取首元素4 ,他会打印4行,并且会声称3个子进程,子进程分别打印3,2,1行,重复上面的入队列
和出队列操作:
queue = " 3