当前位置 : 主页 > 操作系统 > centos >

Linux多进程开发(二)进程创建之vfork的学习

来源:互联网 收集:自由互联 发布时间:2022-06-20
对于Linux多进程开发上篇文章讲解了fork()创建进程,这一篇详细讲解下 vfork()创建进程。 vfork()和fork()有一点不同: 1.vfork()和fork()一样,一次调用,两次返回。 2.fork()创建一个子进程,子

   对于Linux多进程开发上篇文章讲解了fork()创建进程,这一篇详细讲解下 vfork()创建进程。

   vfork()和fork()有一点不同:

   1.vfork()和fork()一样,一次调用,两次返回。

    2.fork()创建一个子进程,子进程只是完全复制父进程的资源,这样的子进程独立于父进程,并发性好

    3.vfork()创建一个子进程时,操作系统并不完全复制父进程的资源,vfork创建的资源共享父进程的地址空间,子进程完全运行在父进程的地址空间上,子进程对该地址空间中任何数据的修改同样父进程

为父进程所见。

    4.vfork()创建一个子进程时,哪个进程先运行取决于系统的调度算法,而vfork一个进程时,vfork保证

子进程先运行,当它调用exec或exit后,父进程才可能被调度运行。

注:如果在调用exec或exit之前子进程要依赖父进程的某个行为,就会导致死锁。


   下面用代码讲解:

# include <unistd.h> # include <sys/types.h> # include <stdio.h> int globVar = 5; int main(void) { pid_t pid; int var = 1, i; printf("fork is diffirent with vfork \n"); pid = fork(); /*pid = vfork()*/ switch(pid) { case 0: i = 3; while(i-- > 0) { printf("Child process is running \n"); globVar++; var++; sleep(1); } printf("Child's globVar = %d, var = %d\n",globVar, var); break; case -1: perror("Process creation failed \n"); exit(0); default: i = 5; while(i-- > 0) { printf("Parent process is runnig \n"); globVar++; var++; sleep(1); } printf("Parent's globVar = %d, var = %d\n", globVar, var); exit(0); } exit(0); }


   此时运行结果如下:

Linux多进程开发(二)进程创建之vfork的学习_创建子进程

   此时用的是fork()创建新进程,分析:

       子进程继承了父进程的全局变量和局部变量,子进程中,最后全局变量globVar和局部变量var均递增3,分别是8和4,而父进程均递增5,结果是10和6,这证明了子进程有自己独立的地址空间。不管是全局变量还是局部变量,子进程和父进程对它们的修改互不影响。

   此时注释带掉pid = fork(); 开始用vfork(),结果如下:

Linux多进程开发(二)进程创建之vfork的学习_Linux_02

   分析:

   vfork()创建了子进程后,父进程中globVar和var都递增了8,因为vfork()的子进程共享父进程的地址空间,子进程修改变量对父进程是可见的。


   fork()创建了子进程之后,父子进程的执行顺序是不确定的。

   vfork()创建子进程之后,子进程先运行,这是因为vfork()是保证子进程先运行的,在子进程调用exit或exec之前父进程是阻塞的状态。

   在进程中:S为阻塞状态。 D为不可中断状态。

   大家可以去ps下去看看。


   特注:使用vfork时要谨慎,最好不要允许子进程修改与父进程共享的全局变量和局部变量。


上一篇:CentOS6.4之Linux软件包管理
下一篇:没有了
网友评论