fork()用法小结

  1. 1、Linux下进程的结构
  2. 一个进程,主要包含三个元素: 一个可以执行的程序;和该进程相关联的全部数据(包括变量,内存空间,缓冲区等等); 程序的执行上下文(execution context)。 
  3. Linux下一个进程在内存里有三部份的数据,就是“数据段”,“堆栈段”和“代码段。“代码段”,顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段。堆栈段存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。 
  4. 2、fork()的使用
  5. fork() creates a child process that differs from the parent process only in its PID and PPID, and in the fact that resource utilizations are set to 0. File locks and pending signals are not inherited.
  6. 一个程序一调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。而如果两个进程要共享什么数据的话,就要使用另一套函数(shmget,shmat,shmdt等)来操作。现在,已经是两个进程了,对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零,这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中。 
  7. 典型的代码如下:
  8. void main(){ 
  9.     if ( fork() == 0 ) { 
  10.         /* 子进程程序 */  
  11.         printf("This is child process/n"); 
  12.     } 
  13.     else { 
  14.          /* 父进程程序*/  
  15.          printf("This is process process/n"); 
  16.     } 
  17. 3、关于fork()性能的疑问
  18. 如果一个大程序在运行中,它的数据段和堆栈都很大,如果fork只是简单地复制所有的数据,那系统开销会变得很大。在Linux系统里面,无论是数据段还是堆栈段都是由许多页构成的,fork函数复制这两个段,只是“逻辑”上的,并非“物理”上的,也就是说,实际执行fork时,物理空间上两个进程的数据段和堆栈段都还是共享着的,当有一个进程写了某个数据时,这时两个进程之间的数据才有了区别,系统就将有区别的“页”从物理上也分开。这就是Linux系统的COW(Copy-On-Write)机制,这样系统在空间上的开销就可以达到最小。 
  19. 在fork()的man page里有关于此的说明:
  20. Under Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent’s page tables, and to create a unique task structure for the child.
  21. 4、fork()后父进程与子进程的调度
  22. 依赖于具体系统的调度算法。如果需要父子进程协同,需要通过原语来解决。

测试结果:

AIX Version 5.3

 

my process id is 1482978 .
process id is 1470702.
process id is 0.

 

测试代码:

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. int main()
  5. {
  6.   pid_t pid = getpid();
  7.   printf("my process id is %d ./n",pid);
  8.   pid = fork(); /** create a child process **/
  9. /*
  10.   if(0 == pid)
  11.   {
  12.     printf("This is child process, process id is %d./n",pid);
  13.     _exit(0);
  14.   }
  15.   else if(0 < pid)
  16.   {
  17.     printf("This is parent process, process id is %d./n",pid);
  18.   }
  19.   else
  20.   {
  21.     perror("unable create the child process.");
  22.   }
  23. */
  24.     printf("process id is %d./n",pid);
  25. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值