← 返回首页
Linux高级程序设计(三十三)
发表时间:2021-11-19 17:19:51
vfork函数

vfork() 函数和 fork() 函数一样都是在已有的进程中创建一个新的进程。

1.vfork与fork的区别

  1. fork(): 父子进程的执行次序不确定。 vfork():保证子进程先运行,在它调用 exec(进程替换) 或 exit(退出进程)之后父进程才可能被调度运行。

  2. fork(): 子进程拷贝父进程的地址空间,子进程是父进程的一个复制品。 vfork():子进程共享父进程的地址空间(准确来说,在调用exec进程替换 或exit退出进程)之前与父进程数据是共享的)。

实例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int pid;

    pid = vfork(); // 创建进程
    if (pid < 0)
    { // 出错
        perror("error to create process:");
        exit(-1);
    }
    if (0 == pid)
    {
        int i;
        for (i = 0; i < 5; i++)
        {
            printf("I am son!\n");
            // 子进程
            sleep(1); // 延时 3 秒
        }
        _exit(0); // 退出子进程,必须
    }
    else if (pid > 0)
    { // 父进程
        printf("i am father\n");
    }
    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
I am son!
I am son!
I am son!
I am son!
I am son!
i am father

实例: 验证子进程共享父进程的地址空间。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int a = 10;
int main(int argc, char *argv[])
{
    int pid;
    int b = 20;
    static int c = 30;
    pid = vfork(); // 创建进程
    if (pid < 0)
    {   // 出错
        perror("vfork");
    }
    if (0 == pid)
    {   // 子进程
        a++; 
        b++;
        c++;
        printf("in son: a = %d, b = %d, c=%d \n", a, b, c);
        _exit(0); // 退出子进程,必须
    }
    else if (pid > 0)
    {   // 父进程
        printf("in father: a = %d, b = %d, c= %d \n", a, b, c);
    }
    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
in son: a = 11, b = 21, c=31 
in father: a = 11, b = 21, c= 31 

注意:vfork()会保证子进程先运行,在它调用exec(进程替换)或 exit(退出进程)之后父进程才可能被调度运行。如果子进程没有调用 exec或者exit, 程序则会导致死锁,程序是有问题的程序,没有意义。