(Apue recording) Process Control: fork and vfork

Source: Internet
Author: User
Tags glob terminates

2013-03-02 wcdj

1 fork -- "Create a new baby"

#include <unistd.h>#include <stdio.h>#include <stdlib.h>int glob = 6;// external variable in initialized datachar buf[] = "a write to stdout\n";intmain(int argc, char** argv){int var;// automatic variable on the stackpid_t pid;var = 88;if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)printf("write error\n");printf("before fork\n");// we do not flush stdoutif ((pid = fork()) < 0){printf("fork error\n");}else if (pid == 0)// child{printf("child's parent pid:%d\n", getppid());glob++;var++;}else{sleep(3);// parent}printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);exit(0);}/*output:mba:APUE gerryyang$ gcc -o fork fork.c mba:APUE gerryyang$ ./fork a write to stdoutbefore forkchild's parent pid:574pid = 575, glob = 7, var = 89pid = 574, glob = 6, var = 88mba:APUE gerryyang$ ./fork > tmp.outmba:APUE gerryyang$ cat tmp.out a write to stdoutbefore forkchild's parent pid:617pid = 618, glob = 7, var = 89before forkpid = 617, glob = 6, var = 88 */

In UNIX, an existing process can use the fork function to create a new process (child process ).

# Include <unstd. h>
Pid_t fork ();

Note:
(1) return value: the child process returns 0, the parent process returns the child process ID, and the error returns-1.
(2) The fork function is called once, but returns two. The only difference between the two responses is that the return value of the child process is 0, and that of the parent process is the ID of the new Child process.
(3) process ID 0 is always used by the kernel switch process, so the process ID of a sub-process cannot be 0.
(4) A sub-process can call getppid to obtain the ID of the parent process.
(5) The child and parent processes continue to execute the commands after the fork call.
(6) A child process is a "copy" of the parent process ". For example, a sub-process obtains a "copy" of the data space, heap, and stack of the parent process ". Note that parent and child processes do not share these buckets. Parent and Child processes share the body segment.
Note: Because exec is often followed after fork, many of the current implementations do not execute full replication of a parent process data segment, heap, and stack, using the copy-on-write (COW) technology, these areas are shared by Parent and Child processes, and the kernel changes their access permissions to read-only, if any parent or child process tries to modify these regions, the kernel will only make a copy of the memory of the region to be modified, usually a "page" in the virtual memory system ".
(7) In general, after fork, whether the parent process is executed first or the child process is executed first is uncertain, depending on the scheduling algorithm used by the kernel. If synchronization between parent and child processes is required, some form of IPC is required.
(8) replication of the buffer zone. The Write function is not buffered, but the standard I/O Library is buffered. When running in interactive mode, only the row output by the printf is obtained once. The reason is that the standard output buffer is rinsed by the line break; but when the standard output is redirected to a file, the reason is that printf is called once before fork, but when fork is called, the row data is still in the buffer, then, when the data space of the parent process is copied to the child process, the buffer is also copied to the child process. At that time, the Parent and Child processes each had a standard I/O buffer with the content of the row. The second printf before exit adds its data to the existing buffer. When each process terminates, it will eventually fl the copies in its buffer.
(9) file sharing. When the standard output of the parent process is redirected, the standard output of the child process is also redirected. In fact, a feature of fork is that all open file descriptors of the parent process are copied to the child process. Each identical open descriptor of the Parent and Child processes shares a file table item. This shared file method allows the Parent and Child processes to use a file offset for the same file.
Note: If the parent and child processes write to the same descriptor file, but there is no form of synchronization, their output will be chaotic.
There are two common scenarios for processing file descriptors after fork:
[1] The parent process waits for the child process to complete.
In this case, the parent process does not need to process its descriptor. After the child process is terminated, the file offset of any shared descriptor that has read and write operations has been updated accordingly.
[2] Parent and Child processes execute different program segments respectively. (Common)
In this case, after fork, the Parent and Child processes disable the file descriptors they do not need, so that they do not interfere with the file descriptors used by the other party. This method is frequently used in network service processes.
(10) Apart from opening a file, many other attributes of the parent process are also inherited by the child process.
(11) The two main causes of Fork failure are:
[1] There are already too many processes in the system.
[2] The total number of processes of the actual user ID exceeds the system limit. Child_max specifies the maximum number of processes that each actual user ID can have at any time.
(11) two fork usage methods:
[1] A parent process wants to copy itself so that the parent and child processes can execute different code segments at the same time. This is common in network service processes. The parent process waits for client service requests. When such requests arrive, the parent process calls fork to process the requests, the parent process continues to wait for the next service request to arrive.
[2] A process needs to execute a different program. This is a common case for shell. In this case, the child process calls exec immediately after the fork returns.

2 vfork -- "the child and mother are the same, used for spawn"

#include <unistd.h>#include <stdio.h>#include <stdlib.h>int glob = 6;// external variable in initialized dataintmain(int argc, char** argv){int var;// automatic variable on the stackpid_t pid;var = 88;printf("before fork\n");// we do not flush stdoutif ((pid = vfork()) < 0)// use vfork{printf("fork error\n");}else if (pid == 0)// child{printf("child's parent pid:%d\n", getppid());// sleep a well for doing somethingsleep(3);printf("child done\n");glob++;var++;_exit(0);// child terminates}// parent continues hereprintf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);exit(0);}/* output:mba:APUE gerryyang$ gcc -o vfork vfork.cmba:APUE gerryyang$ ./vfork before forkchild's parent pid:1030child donepid = 1030, glob = 7, var = 89*/

The call sequence and return value of the vfork function are the same as those of the fork function, but their semantics is different.
# Include <unistd. h>
Pid_t vfork ();

Vfork -- spawn new process in a virtual memory efficient way

Description

Vfork () can be used to create new processes without fully copying the address space

Of the old process, which is horrendously inefficient in a paged environment. It is

Useful when the purpose of Fork (2) wocould have been to create a new system context

An execve. vfork () differs from fork in that the child borrows the parent's memory

And thread of control until a call to execve (2) or an exit (either by a call

Exit (2) or abnormally.) The parent process is suincluded while the child is using its

Resources.

Note:
(1) vfork is used to create a new process, which aims to Exec a new program.
(2) Both vfork and fork create a child process, but it does not completely copy the address space of the parent process to the child process, because the child process will immediately call exec (or exit ), therefore, the address space will not be accessed. Before the child process calls exec or exit, it runs in the space of the parent process. This optimization improves the efficiency in Some UNIX page-based Virtual Memory implementations. No replication is faster than cow partial replication.
(3) vfork ensures that the sub-process runs first. After it calls exec or exit, the parent process can be scheduled to run.
Note: If the sub-process depends on the further action of the parent process before calling these two functions, a deadlock will occur.
(4) In the code snippet, the sub-process changes the glob and VAR variables, and the result also changes the variable values in the parent process. Because the child process runs in the address space of the parent process.
(5) The difference between _ exit and exit. _ Exit: Standard I/O buffer flushing is not performed. Most of the modern implementations of exit are no longer looking for trouble in stream close because the process is about to terminate, when the kernel will close all file descriptors opened in the process and close them in the library, it only increases the overhead and does not bring any benefits.

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.