First, Fork Introduction knowledge
A process, including code, data, and resources assigned to the process. The fork () function creates a process that is almost identical to the original process through a system call.
That is, two processes can do exactly the same thing, but two processes can do different things if the initial parameters or the variables passed in are different.
After a process calls the fork () function, the system first assigns resources to the new process, such as space for storing data and code. And then put all the values of the original process
Copied to a new new process, only a few values are different from the value of the original process. The equivalent of cloning a self.
Let's look at an example:
/ * * fork_test.c * version 1 * Created on:2010-5-29 * author:wangth * * # Include <unistd.h> #include <stdio.h> int main () { pid_t fpid;//fpid indicates the value returned by the fork function int count=0; Fpid=fork (); if (Fpid < 0) printf ("Error in fork!"); else if (Fpid = = 0) { printf ("I am the child process, my process ID is%d/n", getpid ()); printf ("I am father's son/n");//For some people, Chinese looks more straightforward. count++; } else { printf ("I am the parent process, my process ID is%d/n", getpid ()); printf ("I am the child his father/n"); count++; } printf ("Statistic Result:%d/n", count); return 0; }
The operating result is:
I am the child process and my process ID is 5574
I'm the father's son.
The statistic results are: 1
I am the parent process, my process ID is 5573
I'm the kid, his father.
The statistic results are: 1
Before the statement fpid=fork (), only one process is executing this code, but after this statement, it becomes two processes executing, the two processes are almost identical,
The next statement that will be executed is the IF (fpid<0) ...
Why the fpid of two processes is different, which is related to the characteristics of the fork function.
A wonderful thing about a fork call is that it is called only once, but it can return two times, and it may have three different return values:
1) In the parent process, fork returns the process ID of the newly created child process;
2) in the sub-process, fork returns 0;
3) If an error occurs, fork returns a negative value;
After the fork function finishes executing, if the new process is created successfully, there are two processes, one child process and one parent process. In a child process, the fork function returns 0, in the parent process,
Fork returns the process ID of the newly created child process. We can determine whether the current process is a child process or a parent process by the value returned by the fork.
Quote a netizen to explain why the value of Fpid is different in the parent-child process. "In fact, the equivalent of a linked list, the process formed a list, the parent process fpid (p means point) to the process ID of the child process,
Because the child process has no child processes, its fpid is 0.
There are two possible reasons for fork errors:
1) The current number of processes has reached the system-specified limit, when the value of errno is set to Eagain.
2) system memory is low, then the value of errno is set to Enomem.
After a successful creation of a new process, there are two fundamentally identical processes in the system, which do not have a fixed sequencing and which process first executes the process scheduling policy to look at the system.
Each process has a unique (distinct) process ID, which can be obtained through the getpid () function, a variable that records the PID of the parent process, and the value of the variable can be obtained through the getppid () function.
After the fork executes, two processes appear,
Some people say that the content of the two process is exactly the same Ah, how to print the result is not the same ah, that is because the reason for judging the conditions, the above list is only the process of code and instructions, and variables ah.
After the fork is executed, the variable for process 1 is count=0,fpid! =0 (parent process). The variable for process 2 is count=0,fpid=0 (child process), and the variables for both processes are independent,
There are different addresses that are not shared, so be aware of this. We can say that we are using fpid to identify and manipulate parent-child processes.
Others may wonder why the code is not copied from # include, because Fork is a copy of the current situation of the process, and when the fork is executed, the process has executed int count=0;
Fork only copies the next code to execute to the new process.
Second, fork advanced knowledge
Let's look at a piece of code:
/ * * fork_test.c * version 2 * Created on:2010-5-29 * author:wangth * * # Include <unistd.h> #include <stdio.h> int main (void) { int i=0; printf ("I son/pa ppid pid fpid/n"); Ppid refers to the current process of the parent process PID //pid refers to the current process PID, //fpid refers to the value of the fork returned to the current process for (i=0;i<2;i++) { pid_t fpid= Fork (); if (fpid==0) printf ("%d child %4d%4d%4d/n", I,getppid (), Getpid (), fpid); else printf ("%d parent%4d%4d%4d/n", I,getppid (), Getpid (), fpid); } return 0; }
The operating result is:
I son/pa ppid pid fpid
0 Parent 2043 3224 3225
0 Child 3224 3225 0
1 Parent 2043 3224 3226
1 Parent 3224 3225 3227
1 Child 1 3227 0
1 Child 1 3226 0
This code is interesting, let's analyze it carefully:
First step: In the parent process, the instruction executes into the For loop, i=0, and then after execution Fork,fork executes, two processes appear in the system, namely p3224 and p3225
(I use PXXXX to indicate the process ID of xxxx). You can see that the parent process p3224 is p2043, and the parent process p3225 the child process is exactly p3224. We use a linked list to represent this relationship:
p2043->p3224->p3225
After the first fork, the variable for the p3224 (parent process) is i=0,fpid=3225 (the fork function returns to the child process ID in the parent process), with the following code:
for (i=0;i<2;i++) { pid_t fpid=fork ();//execution complete, i=0,fpid=3225 if (fpid==0) printf ("%d child %4d%4d% 4d/n ", I,getppid (), Getpid (), fpid); else printf ("%d parent%4d%4d%4d/n", I,getppid (), Getpid (), fpid); } return 0;
The variable for the p3225 (child process) is i=0,fpid=0 (the fork function returns 0 in the subprocess), and the Code content is:
for (i=0;i<2;i++) { pid_t fpid=fork ();//execution complete, i=0,fpid=0 if (fpid==0) printf ("%d child %4d%4d% 4d/n ", I,getppid (), Getpid (), fpid); else printf ("%d parent%4d%4d%4d/n", I,getppid (), Getpid (), fpid); } return 0;
So print out the results:
0 Parent 2043 3224 3225
0 Child 3224 3225 0
The second step: assume that the parent process p3224 first execution, when entering the next loop, I=1, then the fork, and then a new process p3226 in the system, for the parent process at this time,
p2043->p3224 (current process)->p3226 (the child process being created).
For child process p3225, after the first loop is executed, i=1, then fork, a new process p3227 is added to the system, p3224->p3225 (the current process)->p3227 (the child process being created).
From the output you can see that p3225 was originally a p3224 child process and now becomes the parent process of p3227. Father and son are relative, this people should be easy to understand. As long as the current process has been fork, the process becomes the parent process, which prints out the parent.
So print out the result:
1 Parent 2043 3224 3226
1 Parent 3224 3225 3227
Step three: The second step creates two process p3226,p3227, which ends when the printf function finishes executing, because the two processes cannot enter the third loop, cannot fork, and executes return 0;
Here are the results printed by p3226,p3227:
1 Child 1 3227 0
1 Child 1 3226 0
The attentive reader may notice that p3226,p3227 's parent process should not be p3224 and p3225, how could it be 1? Here we have to talk about the process of creating and dying,
After the second loop is executed by p3224 and p3225, the main function should quit, that is, the process should die, because it has done everything. After the death of p3224 and p3225,
p3226,p3227 There is no parent process, which is not allowed in the operating system, so p3226,p3227 's parent process is set to P1, P1 is never dead, as for why,
Here is not introduced, to stay to the "three, fork higher-level knowledge," said.
To summarize, this program executes the following process:
This program eventually produces 3 sub-processes and executes the printf () function 6 times.
Let's look at one more code:
/ * * fork_test.c * version 3 * Created on:2010-5-29 * author:wangth * * # Include <unistd.h> #include <stdio.h> int main (void) { int i=0; for (i=0;i<3;i++) { pid_t fpid=fork (); if (fpid==0) printf ("son/n"); else printf ("father/n"); } return 0; }
Its execution results are: Father son father father father father son son father son son son father Son here does not explain in detail, only to do a rough analysis. For I=0 1 2 father father father son Son father son son father Father son son father Son each of these lines represents the running print result of a process. Summing up the rules, for this n-cycle situation, the number of times to execute the printf function is 1+2+4+......+2n-1, and the number of child processes created is 1+2+4+......+2n-1. (Thanks to Gao_jiawei Netizens pointed out the mistake, originally I concluded that "the number of times to execute the printf function is 1+2+4+......+2n), the number of sub-processes created is 1+2+4+......+2n", which is wrong) online some people say that n cycles produce a (1+2+4+......+ 2N) process, this statement is wrong, I hope you need to pay attention to. See http://202.117.3.13/wordpress/?p=81 (the Last of the blog post) for mathematical reasoning. At the same time, if you want to test a program in the end to create a few sub-processes, the best way is to call the printf function to print the PID of the process, that is, call printf ("%d/n", Getpid ()), or through printf ("+/n"), to determine the production of several processes. Some people want to count the creation of several processes by invoking printf ("+"), which is not appropriate. I'll analyze it for specific reasons. Old rulesMoment, we look at the following code:
/ * * fork_test.c * version 4 * Created on:2010-5-29 * author:wangth * * # Include <unistd.h> #include <stdio.h> int main () { pid_t fpid;//fpid indicates the value returned by the fork function // printf ("fork!"); printf ("fork!/n"); Fpid = fork (); if (Fpid < 0) printf ("Error in fork!"); else if (Fpid = = 0) printf ("I am the child process, my process ID is%d/n", getpid ()); else printf ("I am the parent process, my process ID is%d/n", getpid ()); return 0; }
The results of the implementation are as follows:
fork!
I am The parent process, my process ID is 3361
I am the child process and my process ID is 3362
If you put the statement printf ("fork!/n"); Comment out, execute printf ("fork!");
The result of the new program execution is:
fork! I am The parent process, my process ID is 3298
fork! I am the child process and my process ID is 3299
The only difference between the program is a/n carriage return symbol, why the result is so big difference?
This is related to the buffer mechanism of printf, when some content of printf, the operating system just put the content in the stdout buffer queue, and did not actually write to the screen.
However, as soon as you see that there is/N, the stdout is refreshed immediately, so you can print immediately.
printf ("fork!") was run After, "fork!" Just put in the buffer, the program runs to the fork buffer inside the "fork!" Quilt process copy passed. So stdout in the degree of sub-progressive
There is also a fork! in the buffer. So, what you finally see is fork!. was printf 2 times!!!
While running printf ("fork! /n ")," fork! " is immediately printed on the screen, and then the stdout buffer in the sub-process to fork will not have fork! Content. So the results you see will be fork!. was printf 1 times!!!
So printf ("+") does not respond correctly to the number of processes.
It may be a bit tiring for everyone to see so much, but I have to stick to the last piece of code to further analyze the fork function.
#include <stdio.h> #include <unistd.h> int main (int argc, char* argv[]) { fork (); Fork () && fork () | | Fork (); Fork (); return 0; }
The problem is not the main process itself, how many processes the program has created.
In order to answer this question, we first do the cheat, first with a program to verify how many processes.
#include <stdio.h> int main (int argc, char* argv[]) { fork (); Fork () && fork () | | Fork (); Fork (); printf ("+/n"); }
The answer is a total of 20 processes, minus the main process, and 19 more processes.
Let's take a closer look at why there are still 19 of processes.
The first fork and the last fork are sure to be executed.
Mainly in the middle of the 3 fork, you can draw a diagram to describe.
Here you need to be aware of && | | Operator.
A&&b, if the a=0, there is no need to continue to implement &&B, a non-0, you need to continue to implement &&b.
a| | B, if A is not 0, there is no need to continue execution | | B, a=0, we need to continue to execute. | | B.
Fork () is different from the return values of the parent and child processes, according to A&&b and a| | B's branch to draw, you can draw 5 branches.
Plus the front fork and the last fork, a total of 4*5=20 process, except main main process, is 19 processes.
Third, fork advanced knowledge
This piece I mainly on the fork function to tell the operating system process creation, death and scheduling. Because of time and energy constraints, I wrote here first, next time I try to get the rest of the content.
Original address: http://blog.csdn.net/jason314/article/details/5640969
The fork () function in Linux is detailed (original!!) examples) (reproduced)