fork 与vfork 的异同

                                      vfork 与fork异同总结

前言

        调⽤fork或vfork函数是Linux创建⼀个新进程的⽅法.

fork

        由fork创建的新进程被称为⼦进程(child process)。该函数被调⽤⼀次,但返回两次。两次返回的区别是⼦进程的返回值是0,⽽⽗进程的返回 值则是新⼦进程的进程ID。

        fork之后经常跟随着exec。作为替代,使⽤了在写时复制(Copy-On-Write,COW)的技术。这些区域由⽗、⼦进程共享,⽽且内核将它们的存取许可权改变为只读的。如果有进程试图修改这些区域,则内核为有关部分,典型的是虚存系统中的“⻚”,做⼀个拷⻉。
 

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

int         globvar = 6;              /* external variable in initialized data */

char       buf[] = "a write to stdout\n";



int

main(void)

{

       int         var;        /* automatic variable on the stack */

       pid_t     pid;



       var = 88;

       if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) //write函数是不带缓存的。

              exit(-1);

        //因为在fork之前调⽤write,所以其数据写到标准输出⼀次。但是,标准I/O库是带缓存的。

       //如果标准输出连到终端设备,则它是⾏缓存的,否则它是全缓存的。

       printf("before fork\n");   /* we don't flush stdout */



       if ((pid = fork()) < 0) {

              exit(-1);

       } else if (pid == 0) {         /* child */

              globvar++;                      /* modify variables */

              var++;

       } else {

              sleep(2);                           /* parent */

       }



       printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);

       exit(0);

}

vfork

        vfork与fork⼀样都创建⼀个⼦进程, 但是它并不将⽗进程的地址空间完全复制到⼦进程中,因为⼦进程会⽴即调⽤exec(或exit), 也就不会存访该地址空间。

        vfork和fork之间的另⼀个区别是:vfork保证⼦进程先运⾏,在它调⽤exec或exit之后⽗进程才可能被调度运⾏。(如果在调⽤这两个函数之前⼦进程依赖于⽗进程的进⼀步动作,则会导致死锁。)

        调用vfork后,如果子进程修改数据、函数调用、或者没有调用exec或exit之后就返回可能会出现未知的错误。

 

测试例子

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>



int main(void)

{

    int count = 1;

    int child;


    printf("Before create son, the father's count is:%d\n", count);

    if((child = vfork())< 0)

    {

        perror("fork error : ");

    }

    else if(child == 0)    

    {

        printf("This is son, his count is: %d (%p). and his pid is: %d\n", ++count, &count, getpid());

        exit(0);  //如果不是exit或exec返回,将会发生未知错误

    }
    else

    {
        printf(" This is father, his count is: %d (%p), his pid is: %d\n", ++count, &count, getpid());

        sleep(1);

    }
    return EXIT_SUCCESS;

}

总结

       fork函数生成的子进程会写时复制的技术对父进程的数据进行复制。父子进程调度根据操作系统的调度来确定。

       vfork函数生成的子进程与父进程共享数据。并优先执行。

 

进程页表的定义

        The page table is where the operating system stores its mappings of virtual addresses to physical addresses, with each mapping also known as a page table entry。参考https://en.wikipedia.org/wiki/Page_table

参考资料

[1].https://stackoverflow.com/questions/20030776/how-can-i-see-a-page-table-maintained-by-each-process-in-virtual-memory-linux

[2].http://man7.org/linux/man-pages/man2/vfork.2.html

[3].http://man7.org/linux/man-pages/man2/fork.2.html

[4].https://www.amazon.com/Advanced-Programming-UNIX-Environment-3rd/dp/0321637739

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fork和vfork是Linux系统中用来创建进程的函数,它们的区别在于进程的创建和共享数据段的方式。当调用fork函数时,父进程会创建一个子进程,并且子进程会拷贝父进程的数据段。子进程在fork之后会执行父进程的代码,但是父子进程的执行顺序是不确定的。而当调用vfork函数时,父进程会创建一个子进程,但是子进程不会拷贝父进程的数据段,而是与父进程共享数据段。在vfork中,子进程会先运行,而父进程会挂起,直到子进程调用了exec或者exit函数,父进程才会被执行。 因此,fork适用于需要在子进程中修改数据的情况,而vfork适用于需要在子进程中立即执行一个新程序的情况。另外,vfork函数的性能比fork函数要好,因为vfork不需要完全拷贝父进程的数据段。然而,由于vfork与父进程共享数据段,所以需要注意在子进程中不要修改共享的数据,以免影响到父进程的执行。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [详解linux中fork、vfork、clone函数区别](https://download.csdn.net/download/weixin_38509656/12844110)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [fork与vfork详解](https://blog.csdn.net/iteye_4389/article/details/82518147)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [fork/vfork详解](https://blog.csdn.net/weixin_36750623/article/details/83041030)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值