进程创建函数之fork()和vfork()

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Fitz1318/article/details/57562251

UNIX操作系统的底层接口:系统调用是用户程序与系统内核的接口。,创建一个新进程的唯一方法是由一个已经存在的进程通过调用fork()、vfork()、和clone()函数来实现。已存在创建者进程叫做父进程,被创建进程叫做子进程。


首先学习的是fork()函数,用该函数创建进程时,语句调用序列如下。

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void)


返回:调用正确时,给父进程返回的是被创建子进程的标识,给子进程返回的是0;创建失败时,返回父进程的是-1.

fork()函数是一个单调用双返回的函数。下面是一个fork()系统调用的使用例子

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int glob = 3;
int main()
{
    pid_t pid;
    int loc = 3;
    printf("before fork(): glob = %d, loc = %d.\n",glob,loc);
    if((pid = fork()) < 0)
    {
       printf("fork() error.\n");
       exit(0);
    }
    else if(pid == 0)
    {
       glob++;
       loc--;
       printf("child process changes glob and loc;\n");
    }
    else
       printf("parent process doesn't change the glob and loc;\n");
    printf("glob = %d, loc = %d\n",glob,loc);
    exit(0);
    return 0;
}


这只是其中一种结果。是因为由于上述程序运行时产生两个进程,由main()函数产生一个父进程以及程序执行中通过fork()产生的一个子进程。当执行到fork()后形成两个并发进程。根据系统调用情况,可能产生两种结果。

PS:fork()函数,子进程拷贝父进程的代码段、数据段,但是父子进程不共享数据段,但是使用Vfork()函数后,父子进程共享数据段。下面来看一下Vfork()函数

 

用Vfork()函数创建进程时,语句调用序列如下

#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void)

返回值:正确返回时与fork()返回值一样,返回子进程标识,否则返回-1.用vfork()函数创建进程时,通常用exec()函数紧跟其后,以便为新创建进程指派另一个可执行程序。用vfork()创建的新进程并不完全复制父进程的数据区。vfork()调用后,子进程先运行,父进程挂起,直到子进程调用exec()或exit()之后,父子进程的执行顺序才不会有限制。否则,如果子进程在调用exec()或exit()之前,父进程被激活,就会造成死锁。

下面给出一个vfork()系统调用的例程

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int glob = 3;
int main()
{
    pid_t pid;
    int loc = 3;
    if((pid = vfork()) < 0)
    {
        printf("vfork() error\n");
        exit(0);
    }
    else if(pid == 0)
    {
        glob++;
        loc--;
        printf("child process changes the glob and loc\n");
        exit(0);
    }
    else
        printf("parent process doesn't change the glob and loc\n");
    printf("glob = %d,loc = %d\n",glob,loc);
    exit(0);
    return 0;
}

这个程序只会产生一个结果,如下图所示

PS;Vfork()函数中父子进程共享数据段。

Vfork()创建进程成功后,父进程挂起,子进程先运行,在父进程的数据区中修改了glob和loc的值,并输出一句话,然后调用exit(0),子进程退出。由于父子进程共享地址空间,父进程继续运行,执行两条输出语句。由此看出glob和loc确实被子进程修改了。这就是vfork()和fork()的区别。

展开阅读全文

没有更多推荐了,返回首页