进程控制1--fork vfork函数

linux系统调用fork()创建一个和当前进程完全相同的拷贝进程,其中父进程和子进程的代码段,堆栈段,数据段均独立

 

进程必须的4要点:

a.要有一段程序供该进程运行

b.进程专用的系统堆栈空间。

c.进程控制块,在linux中具体实现是task_struct

d.有独立的存储空间。

当一个进程缺少其中一个条件时候,我们称其为线程。

 

1.先看fork()的原型 :

 

#include<sys/types.h> /* 提供类型pid_t的定义 */
#include<unistd.h> /* 提供函数的定义 */
pid_t fork(void);
返回: 父进程中执行则返回子进程PID,子进程中执行返回0

 

现在进行一个例子,创建一个子进程,然后根据返回的 PID进行识别:

[cpp]  view plain copy
  1. /*test.c*/  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <unistd.h>  
  5.   
  6. main()  
  7. {  
  8.         int count = 0;  
  9.     pid_t pid;      /*此时仅有一个进程*/      
  10.     pid=fork(); /*此时已经有两个进程在同时运行*/    
  11.     if(pid<0)    /*返回错误*/      
  12.     printf("error in fork!");     
  13.     else   
  14.     {  
  15.     if(pid==0)      /*代码在子进程中执行*/  
  16.         printf("I am the child process, my count is %d,my process ID is %d/n",count,getpid());  
  17.     else        /*代码在父进程中执行*/  
  18.         printf("I am the parent process,my count is %d, my process ID is %d/n",++count,getpid());  
  19.     }  
  20. }  

弄好后,在linux中键入:

 

$ gcc test.c -o test

$ ./test

 

在本次试验中

 

I am the parent process,my count is 1,my process ID is 3196

I am the child process, my count is 0,my process ID is 3776

 

 从代码里面可以看出2者的pid不同,内存资源count是值得复制,父进程改变了count的值,而子进程中的count没有被改变。有人认为这样大批量的复制会导致执行效率过低。其实在复制过程中,子进程复制了父进程的task_struct,系统堆栈空间和页面表,这意味着上面的程序,我们没有执行count++前,其实子进程和父进程的count指向的是同一块内存。而当子进程改变了父进程的变量时候,会通过copy_on_write的手段为所涉及的页面建立一个新的副本。所以当我们执行++count后,这时候子进程才新建了一个页面复制原来页面的内容,基本资源的复制是必须的,而且是高效的。整体看上去就像是父进程的独立存储空间也复制了一遍。

 

在fork中,父子进程是独立开来的 ,并没有影响

 

2.vfork函数

vfork创建出来的不是真正意义上的进程,而是一个线程,因为它缺少了上面提到的进程的四要素的第4项,独立的内存资源,我们编一个程序练习:

[cpp]  view plain copy
  1. #include <sys/types.h>  
  2. #include <sys/stat.h>  
  3. #include <unistd.h>  
  4.   
  5. main()   
  6. {  
  7.         int count = 1;  
  8.         int child;  
  9.   
  10.         printf("Before create son, the father's count is:%d/n", count);//打印没创建进程前  
  11.         if(!(child = vfork())) //创建子进程  
  12.     {  
  13.                 printf("This is son, his pid is: %d and the count is: %d/n", getpid(), ++count);  
  14.                 exit(1);  
  15.         } else   
  16.     {  
  17.                 printf("After son, This is father, his pid is: %d and the count is: %d, and the child is: %d/n",      
  18.   
  19.     getpid(), count, child);  
  20.         }  
  21. }  

 

然后编译,执行,得到下列结果:

Before create son, the father's count is:1

This is son, his pid is: 4048 and the count is: 2
After son, This is father, his pid is: 4048 and the count is: 2, and the child is: 2748

从这里我们看到,子进程和父进程是共享count的,也就是说,内存区是共享的

另外由vfork创造出来的子进程还会导致父进程挂起,除非子进程exit或者execve才会唤起父进程,看下面程序:

[cpp]  view plain copy
  1. #include <sys/types.h>  
  2. #include <sys/stat.h>  
  3. #include <unistd.h>  
  4.   
  5. main()   
  6. {  
  7.         int count = 1;  
  8.         int child;  
  9.   
  10.         printf("Before create son, the father's count is:%d/n", count);  
  11.         if(!(child = vfork()))  
  12.      {//这里是子进程执行区  
  13.                 int i;  
  14.                 for(i = 0; i < 100; i++)   
  15.         {  
  16.                         printf("This is son, The i is: %d/n", i);  
  17.                         if(i == 70)  
  18.                                 exit(1);  
  19.                 }  
  20.                 printf("This is son, his pid is: %d and the count is: %d/n", getpid(), ++count);  
  21.                 exit(1);//子进程退出  
  22.         }   
  23.     else  
  24.      {//父进程  
  25.                 printf("After son, This is father, his pid is: %d and the count is: %d, and the child is: %d/n",      
  26.   
  27.     getpid(), count, child);  
  28.         }  
  29. }  

好,编译通过,执行。。。

Before create son, the father's count is:1

This is son, The i is: 0

...

...

This is son, The i is: 68
This is son, The i is: 69
This is son, The i is: 70
After son, This is father, his pid is: 2564 and the count is: 1, and the child is: 2736

 

可以看到父进程总是等子进程执行完毕后才开始继续执行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值