Vfork and fork (reprint)

Source: Internet
Author: User
Tags call back glob

Recently learned some knowledge about unix/linux C programming, a general understanding of file descriptor-based IO, stream-based IO, process, interprocess communication, signaling, network programming, GTK + programming, and its corresponding related APIs, after reading it feels like this, even some arrogance, These are the things that sound so advanced, but at the same time they are puzzled: how can it be, definitely not the first impression I feel, there is definitely a lot I don't know.

Fortunately, the night did not stroll Chenhao's Coolshell, saw an article "Vfork hung up a problem", only to feel their first feeling is how ignorant, not it simple, but because of the difficult, complex I do not know just. So keep an open mind and thirst for knowledge. The following article references Chenhao:

In the knowledge, there is a person asked such a question-why vfork in the child process with return, the entire program will be hung, and exit () will not? and give the following code, the following code is run off, but if the process of return to exit (0) is OK.

I was invited to do not want to answer this question, because the problem is obviously RTFM, and later, found that the problem was put there for a long time, and hang in the following a few answers and run more serious, I think some friends may see that the answer will be misleading, so went up to answer this question.

Here I will post the question and my answer here, also for more people to view.

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main (void) {    int var;    var = n;    if (PID = Vfork ()) < 0) {        printf ("Vfork error");        Exit ( -1);    } else if (PID = = 0) {/* child process */        var++;        return 0;    }    printf ("pid=%d, glob=%d, var=%d\n", Getpid (), Glob, Var);    return 0;}

Basic Knowledge

First, the difference between fork and vfork:

    • Fork is to create a child process and copy the parent process's memory data into the child process.
    • Vfork is to create a child process and use it with the memory data share of the parent process.

The difference between the two is that one is copy and the other is share. (For fork, you can see the "fork in the face" before the cool shell)

You man vfork a little, you can see, vfork is such a job,

1) Ensure that the child process is executed first.
2) When the child process calls exit () or exec (), the parent process executes down.

So, why do you want to do a vfork this thing? The reason is also very clear on the man page:

Historic Description

Under Linux, fork (2) is implemented using Copy-on-write Pag ES, so the-penalty incurred by Fork (2) are 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 afterwards an exec (3) is D One. Thus, for greater efficiency, BSD introduced the vfork () system call, which do not fully copy the address space of the PA Rent process, but borrowed the parent's mem ory and thread of control until a call to Execve (2) or an exit occurred. The parent process is suspended while the child is using its resources. The use of Vfork () is tricky:for example, not modifying data in the parent process depended on knowing which variables a Re held in a register.

This means-- at first fork, but many programs exec an external program after fork a sub-process, so the fork needs to copy the parent process's data this action becomes meaningless, and this is very heavy (note: Later, fork was optimized, As described later in this article),BSD has a parent-child process shared vfork, which is less expensive. Therefore, Vfork was born to exec.

Why does return hang, exit () not?

From the above we know that the call to end the child process is exit () instead of return, if you return in vfork, then this means that the main () function return, note because the function stack parent-child process is shared, so the entire program stack is kneeling.

If you return in a subprocess, it is basically the following procedure:

1) The main () function of the child process is return, and the function stack of the program has changed.

2) when the main () function is return, exit () or similar function (for example: _exit (), Exitgroup ()) is usually called.

3) At this time, the parent process receives the child process exit (), start returning from the Vfork, but the old man's stack is your child process to return the dry waste, how do you let me do? (note: The stack will return a strange stack address, for some kernel version implementation, directly reported "Stack error" on the kneeling, however, for some kernel version of the implementation, it is possible to call main () again, and then entered an infinite loop result, until the vfork call back Error

OK, now return to return and Exit,return will release the local variable, and play the stack, back to the upper function execution. Exit directly. If you use C + + you know that return calls the destructor of the local object, exit does not. (Note: Exit is not a system call, it is an encapsulation of glibc to System call _exit () or _exitgroup ())

As can be seen, the child process call exit () does not modify the function stack, so the parent process executes smoothly .

About the optimization of fork

Obviously, the fork is too heavy, and the vfork is too dangerous, so someone will start optimizing the fork for this system call. The optimized technology uses the famous write- time copy (COW).

That is, instead of copying the memory immediately after the fork, it is only when you need to change that it is copied from the parent process to the child process, so the cost of executing the exec immediately after the fork is very small . So, the man page of Linux does not encourage the use of vfork ()--

"It's rather unfortunate that Linux revived this specter from the past. The BSD man page states: ' This system call would be eliminated when proper system sharing mechanisms is implemented. Users should not depend on the memory sharing semantics of vfork () as it would, in this case, being made synonymous to fork (2) .””

So, starting with BSD4.4, they made vfork and fork the same.

But later, NetBSD 1.3 again the traditional vfork to pick back, said is Vfork performance in Pentium Pro 200MHz machine (this machine good antique AH) on the can improve a few seconds of performance. See for details-"NetBSD documentation:why implement traditional vfork ()"

Today's Linux, fork and Vfork are still each, however, it is recommended that you do not use vfork, unless you are very concerned about performance.

Vfork and fork (reprint)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.