出错:返回-1;
一个进程主要包括以下几个方面的内容:
(1)一个可以执行的程序
(2) 与进程相关联的全部数据(包括变量,内存,缓冲区)
(3)程序上下文(程序计数器PC,保存程序执行的位置)
这里主要复习一下,fork()的执行和几个需要注意的地方,此外还有几个问题。
第一:COW(Copy-On-Write)写时复制技术,其实在 这里也有讲到,这里再重复一下!#include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> int main() { int num=11; pid_t pid=fork(); if(pid==0) { num=22'; printf("子进程中num=%d\n",num); printf("子进程中num的首地址:%x\n",&num); } else { sleep(1); printf("父进程中num=%d\n",num); printf("父进程中num的首地址:%x\n",&num); } return 0; }
运行结果:
从运行结果来看,发现fork()函数确实创建了两个函数,并且每个函数独立运行,变量也不共享,子进程确实复制了父进程的资源,不然num的值会一样。#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { int i; for(i=0; i<3; i++) { fork(); printf("*\n"); //进程里打印的; } printf(" +\n"); //代表创建的进程数; return 0; }
运行结果:
运行的结果乍一看可能不太懂,让我慢慢来解释,*号代表每个进程都会打印出一个*,+号代表的是创建的进程数。因为这里的进程不是共享一个变量,所以我想用count计数器来计数,却办不到,因为每个计数器count都是从1开始的,最后还得加起来,看起来更乱,所以我就用*和+来表示更直观。这也证明了一个问题,那就是fork出的函数确实是资源空间的复制而不是指针的复制(vfork)!!很好!
因为fork是父进程创建一个子进程,所以为什么*会比+多,是因为进程有重复的,但是退出是一定的且只会退出一次,所以+刚好可以代表创建了几个进程。仔细想一想就会明白了。。。
其实其进程创建的过程是这样的:
数字代表进程号,这就是具体产生的过程。
下面我们可以通过查看其PID看一下创建的进程:
从图中可以看出:共产生了进程6773,6774,6775,6776,6777,6778,6779,6780,这8个进程。
所以打印14个*,8个+号,到这里应该明白了吧!
这里还存在一个复制缓冲区的问题:
如果将上面的输入格式:
printf("*\n"); 或者: printf("*");fflush(stdout);
换成:
printf("*");
那么结果将打印24个*号!这是因为printf(“*”);语句有buffer,所以,对于上述程序,printf(“*”);把“*”放到了缓存中,并没有真正的输出在fork的时候,有点儿exit()和_exit()的意思!缓存被复制到了子进程空间,所以,就多了10个,就成了24个,而不是14个。这个可以自己动手实践一下就明白了!
另外,我们知道,unix系统下有“块设备”和“字符设备”之分,所谓块设备就是一块一块的读取数据的设备,如磁盘,内存;字符设备就是一个字符一个字符的读取,例如键盘,串口等。块设备一般都有缓存,而字符设备一般没有缓存。
问题一:linux下PID的取值范围?问题六:fork()之后子进程到底复制了父进程什么?
关于fork函数中的内存复制和共享“子进程复制父进程的数据空间(数据段)、栈和堆,父、子进程共享正文段。”也就是说,对于程序中的数据,子进程要复制一份,但是对于指令,子进程并不复制而是和父进程共享,除非执行exec函数,另起炉灶。两者的虚拟空间不同,但其对应的物理空间是同一个。
写时复制技术(重要的事情说两遍):内核只为新生成的子进程创建虚拟空间结构,但是不为这些段分配物理内存,它们共享父进程的物理空间,当子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。但是vfork()创建的线程,就是内核连子进程的虚拟地址空间结构也不创建了,直接共享了父进程的虚拟空间。
资料参考:
http://blog.csdn.net/xy010902100449/article/details/44851453
http://www.cnblogs.com/blankqdb/archive/2012/08/23/2652386.html
http://blog.chinaunix.net/uid-24774106-id-3361500.html
http://www.linuxidc.com/Linux/2015-03/114888.htm
http://blog.csdn.net/lollipop_jin/article/details/8774057
在此感谢博主的分享!