精华内容
下载资源
问答
  • vfork

    2021-03-17 23:00:42
    pid_t vfork(void) 作用: 通过复制父进程创建一个子进程,父子进程公用同一块虚拟空间。 创建子进程后,父进程会阻塞直到子进程exit退出或者(程序替换)之后才会运行。 公用同一个虚拟地址空间,同时运行会造成栈...

    1.函数原型:
    pid_t vfork(void)

    2.作用:
    通过复制父进程创建一个子进程,父子进程公用同一块虚拟空间。
    创建子进程后,父进程会阻塞直到子进程exit退出或者(程序替换)之后才会运行。
    3.思考:为什么父子进程不能同时进行?
    公用同一个虚拟地址空间,同时运行会造成栈混乱;
    举个例子:
    main函数进入函数调用栈之后,父进程先运行printf函数,printf函数入栈,时间片完后再切换到子进程运行strcpy函数,strcpy函数入栈,然而strcpy函数运行了一段时间后,时间片完,继续切换到父进程,这时再次调用printf函数,那么strcpy函数就要出栈,函数栈就会发生混乱。
    图示如下:
    在这里插入图片描述

    4.需要注意的点:
    vfork创建的子进程不能在main函数中return退出,但可以使用exit退出。
    原因如下:
    因为return退出不仅仅释放的是子进程的资源,父进程和子进程共用资源,父进程的资源也被释放,那么父进程也被迫退出。而exit仅仅退出的是子进程,释放的是子进程自己的PCB,父进程并不会受到影响。

    代码示例:

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    //vfork创建的子进程先于父进程先运行
    int main()
    {
    printf("Good Morning!Linux\n");
    pid_t pid=vfork();
    if(pid==-1)
            printf("创建子进程失败\n");
    else if(pid==0)
    {
            printf("这是子进程\n");
            //return 1;//子进程使用return,最后会显示segmentation fault
            exit(0);
    }
    else
    {
            printf("这是父进程\n");
    }
    return 0;
    }
    
    

    运行结果:
    在这里插入图片描述

    展开全文
  • vfork函数

    2021-05-19 22:18:30
    vfork函数也可以创建进程,但是与fork有两点关键区别。 关键区别一: vfork直接使用父进程存储空间,不拷贝。 关键区别二: vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。 demo: #include ...

    vfork函数也可以创建进程,但是与fork有两点关键区别。

    关键区别一:

    vfork直接使用父进程存储空间,不拷贝。

    关键区别二:

    vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。

    demo:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main ()
    {
    
       int pid;
    
       /*vfrok函数也可以创建子进程*/
       /*vfork函数直接使用父进程的存储空间,不拷贝*/
       /*vfork函数保证子进程先运行,当子进程调用exit退出后,父进程才运行*/
    
       int i = 0;
    
       pid = vfork();
    
       /*child process*/
       if(pid == 0)
       {
               while(1)
               {
                       i++;
                       sleep(1);
                       printf("current process is child process!\n");
                       if(i == 6)
                       {
                          exit(-1);
    
                       }
               }
    
       }
       /*father process*/
       else if(pid > 0)
       {
               while(1)
               {
                       printf("%d\n",i);
                       sleep(1);
                       printf("current process is father process!\n");
               }
       }
    
    
    
    
        return 0;
    }
    

     

    展开全文
  • vfork文档

    2020-01-30 19:02:07
    VFORK(2) Linux Programmer’s Manual ...

    VFORK(2)

    NAME

    vfork - create a child process and block parent

    vfork - 创建一个子进程并阻塞父进程

    SYNOPSIS

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

    DESCRIPTION

    Standard description
    (From POSIX.1) The vfork() function has the same effect as fork(2), except that the behavior is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from
    the function in which vfork() was called, or calls any other function before successfully calling _exit(2) or one of the exec(3) family of functions.

    标准描述
         标准描述: (始于POSIX.1) vfork函数和fork有相同的效果, 不同点在于vfork的以下行为是不确定的:
        1 修改除vfork返回的用于存储pid_t之外的其他变量.
        2 在调用_exit(2) 或者exec(3)系列函数之前调用其他方法.

    Linux description
        vfork(), just like fork(2), creates a child process of the calling process. For details and return value and errors, see fork(2).
        vfork() is a special case of clone(2). It is used to create new processes without copying the page tables of the parent process. It may be useful in performance-sensitive applications where a child is created which then immediately issues an execve(2).
        vfork() differs from fork(2) in that the calling thread is suspended until the child terminates (either normally, by calling _exit(2), or abnormally, after delivery of a fatal signal), or it makes a call to execve(2). Until that point, the child shares all memory with its parent, including the stack. The child must not return from the current function or call exit(3), but may call _exit(2).
        As with fork(2), the child process created by vfork() inherits copies of various of the caller’s process attributes (e.g., file descriptors, signal dispositions, and current working directory); the vfork() call differs only in the treatment of the virtual address space, as described above.
        Signals sent to the parent arrive after the child releases the parent’s memory (i.e., after the child terminates or calls execve(2)).

        vfork(), 比较像fork(2), 用于创建调用进程的子进程. 详细的返回值和错误信息请参考fork(2).
        vfork() 是clone(2)函数的一个特殊用例. 用于创建一个新的进程但是不拷贝父进程的页表. 它应该用于性能敏感的应用程序,创建完子进程立即执行execve(2) 函数.
        vfork()和fork(2)的不同点在于 vfork调用进程(父进程)将被挂起,直到子进程结束(正常结束, 调用_exit(2), 或者异常,收到致命的信号), 或者调用execve(2)系函数. 在调用完vfork那个时间点. 子进程将共享父进程的所有内存, 包括栈. 子进程不能直接返回或者调用exit(3), 但是可以调用_exit(2).
        和fork(2)相同点在于vfork()创建的子进程也拷贝父进程的属性变量(包括文件描述符, 信号处理, 当前工作目录). vfork调用仅在处理虚拟地址空间方面和fork(2)有所不同. 如上所述.
        信号发送给父进程直到子进程释放和父进程共享的内存.(也就是当子进程结束或者调用execve(2)系函数之后)

    Historic description
    Under Linux, fork(2) is implemented using copy-on-write pages, so the only penalty incurred by fork(2) is the time and memory required to duplicate the parent’s page tables, and to create a unique task structure for the child. However, in the bad old days a
    fork(2) would require making a complete copy of the caller’s data space, often needlessly, since usually immediately afterward an exec(3) is done. Thus, for greater efficiency, BSD introduced the vfork() system call, which did not fully copy the address space of
    the parent process, but borrowed the parent’s memory and thread of control until a call to execve(2) or an exit occurred. The parent process was suspended while the child was using its resources. The use of vfork() was tricky: for example, not modifying data in
    the parent process depended on knowing which variables were held in a register.

        在Linux中,fork(2) 是使用写时复制页面, 因此唯一的开销就是复制父进程页表和创建子进程的task结构所花费的时间和内存. 然而在过去糟糕的日子里, fork需要完整的拷贝父进程的所有数据空间, 在通常是没有必要的,一般情况下fork创建子进程后会马上调用exec(3)系列函数(调用exec系列函数后从父进程拷贝的内存将被释放). 为了更好的体验,BSD发行版引入了vfork系统调用, 它不完全拷贝父进程的地址空间, 但是借用父进程的内存空间和县城控制直到推出或者调用execve(2). 父进程被挂起直到子进程拥有自己的资源(内存空间). 使用vfork是tricky的: 例如,不修改父进程中的数据取决于知道哪些变量保存在寄存器中。

    CONFORMING TO
         4.3BSD; POSIX.1-2001 (but marked OBSOLETE). POSIX.1-2008 removes the specification of vfork().

        The requirements put on vfork() by the standards are weaker than those put on fork(2), so an implementation where the two are synonymous is compliant. In particular, the programmer cannot rely on the parent remaining blocked until the child either terminates or calls execve(2), and cannot rely on any specific behavior with respect to shared memory.

        vfork的标准需求弱于fork(2), 所以一种实现的两个函数实现相同. 特别是,在子进程终止或调用execve(2)之前,程序员不能依赖仍被阻塞的父进程,也不能依赖与共享内存相关的任何特定行为。

    NOTES
        Some consider the semantics of vfork() to be an architectural blemish, and the 4.2BSD man page stated: “This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of vfork() as it will, in that case, be made synonymous to fork(2).” However, even though modern memory management hardware has decreased the performance difference between fork(2) and vfork(), there are various reasons why Linux and other systems have retained vfork():
    * Some performance-critical applications require the small performance advantage conferred by vfork().
    * vfork() can be implemented on systems that lack a memory-management unit (MMU), but fork(2) can’t be implemented on such systems. (POSIX.1-2008 removed vfork() from the standard; the POSIX rationale for the posix_spawn(3) function notes that that function, which provides functionality equivalent to fork(2)+exec(3), is designed to be implementable on systems that lack an MMU.)

        一些人认为vfork()的语义是一个架构缺陷,4.2BSD手册页指出:“当实现适当的系统共享机制时,将消除此系统调用。用户不应该依赖vfork()的内存共享语义,因为在这种情况下,它将成为fork(2)的同义词。“然而,尽管现代内存管理硬件降低了fork(2)和vfork()之间的性能差异,但Linux和其他系统保留vfork()的原因是多方面的:

        *一些性能关键的应用程序需要vfork()所赋予的小性能优势。

        *vfork()可以在缺少内存管理单元(MMU)的系统上实现,但fork(2)不能在此类系统上实现。(POSIX.1-2008从标准中删除了vfork();POSIX_spawn(3)函数的POSIX基本原理指出,该函数提供了相当于fork(2)+exec(3)的功能,设计用于在缺少MMU的系统上实现。)

    Linux notes
         Fork handlers established using pthread_atfork(3) are not called when a multithreaded program employing the NPTL threading library calls vfork(). Fork handlers are called in this case in a program using the LinuxThreads threading library. (See pthreads(7) for a description of Linux threading libraries.)
        A call to vfork() is equivalent to calling clone(2) with flags specified as:
             CLONE_VM | CLONE_VFORK | SIGCHLD

        当使用NPTL线程库的多线程程序调用vfork()时,不会调用使用pthread_atfork(3)建立的Fork处理程序。在本例中,Fork处理程序是在使用LinuxThreads线程库的程序中调用的。(参见pthreads(7)了解Linux线程库的说明。)
        调用vfork()等同于使用指定为的标志调用clone(2):
             CLONE_VM | CLONE_VFORK | SIGCHLD

    History
    The vfork() system call appeared in 3.0BSD. In 4.4BSD it was made synonymous to fork(2) but NetBSD introduced it again, cf. ⟨http://www.netbsd.org/Documentation/kernel/vfork.html⟩. In Linux, it has been equivalent to fork(2) until 2.2.0-pre6 or so. Since
    2.2.0-pre9 (on i386, somewhat later on other architectures) it is an independent system call. Support was added in glibc 2.0.112.

    BUGS
        Details of the signal handling are obscure and differ between systems. The BSD man page states: “To avoid a possible deadlock situation, processes that are children in the middle of a vfork() are never sent SIGTTOU or SIGTTIN signals; rather, output or ioctls are allowed and input attempts result in an end-of-file indication.”

    BUGS
        信号处理的细节不清楚,系统之间也不尽相同。BSD手册页指出:“为了避免可能的死锁情况,vfork()中间的子进程永远不会发送SIGTTOU或SIGTTIN信号;相反,允许输出或ioctl,并且输入尝试会导致文件结束指示。”

    展开全文
  • LINUX vfork

    2017-07-04 21:06:00
    vfork 和fork 一样,执行一次,返回2次。 使用fork创建子进程,子进程完全复制父进程资源,这样得到的子进程独立于父进程,具有良好的并发性。 使用vfork创建子进程,操作系统并不将父进程的地址空间完全复制到子...

    vfork 和fork 一样,执行一次,返回2次。

    使用fork创建子进程,子进程完全复制父进程资源,这样得到的子进程独立于父进程,具有良好的并发性。

    使用vfork创建子进程,操作系统并不将父进程的地址空间完全复制到子进程中。

    用vfork创建的子进程共享父进程的地址空间。子进程完全运行在父进程的地址空间上。

    子进程对该地址空间任何数据的修改在父进程中也可见。

    展开全文
  • vfork Function

    2016-02-28 13:04:14
    调用方法和返回值与fork一样vfork - create a child process and block parent#include #include <unistd.h>pid_t vfork(void);vfork和fork的semantics不同 和fork一样创建新的进程, 但child不引用的地址空间,不会...
  • vfork简单介绍

    2015-06-24 20:22:19
    在linux下通过C语言实现了fork与vfork的区别,里面有源码,可以用gcc编译运行分析
  • fork VS vfork

    2021-06-29 10:31:06
    fork 和vfork 都可以创建一个子进程 fork: 创建和当前进程映像一样的进程 子进程中返回0 , 父进程返回子进程的pid。子进程拷贝父进程的代码段和数据段,同时父子执行顺序不确定,所以获取到子进程pid 需要对返回...
  • vfork()

    千次阅读 2019-05-17 16:23:29
    vfork():sys_vfork() 经过系统调用sys_vfork()进入do_fork()时, 因其clone_flags为 VFORK | CLONE_VM | SIGHLD, 所以只执行了copy_files()、copy_fs()以及copy_sighand 而copy_mm(),则因标志位CLONE_VM为1,只是...
  • vfork实现

    2017-03-14 08:01:39
    #ifdef __ARCH_WANT_SYS_VFORK SYSCALL_DEFINE0(vfork) {  return _do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,  0, NULL, NULL, 0); } #endif
  • vfork存在意义

    2019-06-23 19:27:51
    vfork存在意义:由于他创建进程时与父进程公用一块地址空间,那么他的创建进程的效率很高。 但是fork后来实现了写时拷贝技术,他的效率大大提高,而且进程独立,所以vfork就被淘汰来 `` //这是个体会vfork()的demo 5...
  • vfork的坑

    2021-07-25 19:57:42
    需要特别注意:部分文档或资料说明vfork和fork没有差别,实际上是有差别的,而且在代码调用时要特别小心一点: vfork在调用exev系列函数之前,对父进程变量的修改都会直接会直接改变父进程中该变量的值! 实例1...
  • vfork创建进程

    2020-12-12 18:27:31
    vfork函数也可以创建进程,返回值与fork的返回值一样,与fork有什么区别呢? 区别一:vfork函数直接使用父进程的存储空间,不拷贝。(fork:子进程拷贝父进程的数据段,代码段;vfork:子进程与父进程共享数据段)...
  • vfork 和 exit

    2019-04-06 18:02:09
    vfork 对于创建一个子进程,我们最常用的就是 fork,但其实 vfork 也是用来创建子进程的,但 vfork 和 fork 的差距却是非常大的。 fork 的父子进程各自拥有独立的程序地址空间,在运行时互不干扰;而 vfork 父子...
  • fork与vfork

    2021-03-24 20:10:20
    vfork直接运用父进程存储空间,不拷贝,vfork保证子进程先运行,运行结束后(exit后)父进程再运行。 先看看fork的程序运行 #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #...
  • 创建一个新进程的方法只有由某个已存在的进程调用fork()或vfork()1.fork()函数返回值:成功:父进程:返回子进程的PID子进程:返回0失败:父进程返回-1子进程是父进程的一个拷贝。即子进程从父进程得到数据段和堆、...
  • Linux vfork简介

    2017-05-31 22:20:16
    Linux vfork简介
  • fork和vfork

    2019-06-14 14:41:36
    在知乎上,有个人问了这样的一个问题——为什么vfork的子进程里用return,整个程序会挂掉,而且exit()不会?并给出了如下的代码,下面的代码一运行就挂掉了,但如果把子进程的return改成exit(0)就没事。 我受邀后...
  • 神奇的vfork

    2019-03-06 12:20:02
    一段神奇的代码 在论坛里看到下面一段代码: int createproc(); int main() { pid_t pid = createproc(); printf( "%d\n", pid );...(pid = vfork() ) ) { printf( "chil...
  • vfork与fork

    2020-03-22 11:19:01
    fork()与vfock()都是... vfork( ):子进程与父进程共享数据段 2. fork ()父子进程的执行次序不确定 vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec 或exit 之后父进程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,482
精华内容 5,392
关键字:

vfork