Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the specific use of fork function in Linux system?

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article shows you the specific use of the fork function in the Linux system, the content is concise and easy to understand, it can definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.

First, introduction to fork

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 if the initial parameters or the variables passed in are different, the two processes can also do different things.

After a process calls the fork () function, the system first allocates resources to the new process, such as the space to store data and code. Then copy all the values of the original process to the new process, except for the few values that are different from those of the original process. It's the equivalent of cloning yourself.

Let's look at an example:

/ * * fork_test.c * version 1 * Created on: 2010-5-29 * Author: wangth * / # include # include int main () {pid_t fpid; / / fpid represents the value returned by the fork function int count=0; fpid=fork (); if (fpid printf ("error in fork!"); else if (fpid= = 0) {printf ("i am the child process, my process id is% dmen", getpid ()) Printf ("I am my father's son / n") / / Chinese looks more straightforward to some people. Count++;} else {printf ("i am the parent process, my process id is% DSPO", getpid ()); printf ("I am the father of the child / n"); count++;} printf ("Statistical result:% dBO", count); return 0;} run result is:

I am the child process, my process id is 5574 I am the father's son, the statistics are: 1 i am the parent process, my process id is 5573 I am the father of the child, the statistics are: 1

Before the statement fpid=fork (), only one process is executing this code, but after this statement, two processes are executing, the two processes are almost identical, and the next statement to be executed is if (fpid

Why the fpid of the two processes is different has something to do with the nature of the fork function. One of the wonders of a fork call is that it is called only once, but it can return twice, and it may have three different return values:

1) in the parent process, fork returns the process that created the new child process ID; 2) in the child process, fork returns 0; 3) if an error occurs, fork returns a negative value

After the execution of the fork function, if the new process is created successfully, two processes appear, one is the child process, and the other is the parent process. In the child process, the fork function returns 0, and in the parent process, fork returns the process ID that created the new child process. We can determine whether the current process is a child process or a parent process by the value returned by fork.

Quote a netizen to explain why the value of fpid is different in parent-child processes. "in fact, it is equivalent to a linked list, and the process forms a linked list. The fpid (p means point) of the parent process points to the process id of the child process. Because the child process does not have a child process, its fpid is 0.

There are two possible reasons for fork errors:

1) the current number of processes has reached the upper limit specified by the system, and the value of errno is set to EAGAIN. 2) the system is out of memory, so the value of errno is set to ENOMEM.

After the creation of a new process is successful, two basically identical processes appear in the system. There is no fixed order in which the two processes are executed. Which process executes first depends on the process scheduling policy of the system.

Each process has a unique (different) process identifier (process ID), which can be obtained through the getpid () function, and 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 execution of the fork, two processes appear

Some people say that the contents of the two processes are exactly the same, ah, how to print the results are different, that is because of the judgment conditions, the above list is only the code and instructions of the process, as well as variables.

After executing the fork, the variable for process 1 is count=0,fpid! = 0 (parent process). The variable of process 2 is count=0,fpid=0 (child process). It should be noted that the variables of the two processes are independent, exist in different addresses, and are not shared. It can be said that we identify and operate parent-child processes through fpid.

Others may wonder why the code is not copied from # include, because fork makes a copy of the current situation of the process, and when fork is executed, the process has already finished int count=0;fork and only copies the next code to be executed to the new process.

Second, fork advanced knowledge

Take a look at a code first:

/ * * fork_test.c * version 2 * Created on: 2010-5-29 * Author: wangth * / # include # include int main (void) {int item0; printf ("I son/pa ppid pid fpid/n"); / / ppid refers to the parent process of the current process pid/ / pid refers to the pid of the current process, / / fpid refers to the value for (item0transiting I pid_t fpid=fork () returned by fork to the current process) If (fpid==0) printf ("% d child% 4d% 4d% 4d/n", getpid (), fpid); else printf ("% d parent% 4d% 4d% 4d/n", iMed getppid (), getpid (), fpid);} return 0;} run result:

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:

The first step: in the parent process, the instruction is executed in the for loop, iS0, and then after the execution of fork,fork, there are two processes in the system, p3224 and p3225 (later I use pxxxx to represent the process id is the process of xxxx). You can see that the parent process of the parent process p3224 is p2043 and the parent process of the child process p3225 is exactly p3224. We use a linked list to represent this relationship:

P2043-> p3224-> p3225

After the first fork, the variable of the p3224 (parent process) is iDiverence fpidprocesses 3225 (the fork function returns to the child process id in the parent process), and the code content is as follows:

When the execution is completed, for (igrad0 pid_t fpid=fork) if (fpid==0) printf ("% d child% 4d% 4d% 4d/n", "% d parent% 4d% 4d% 4d/n", getpid (), fpid); else printf ("% d parent% 4d% 4d% 4d/n", ijigent getppid (), getpid (), fpid);} return 0transp3225 (child process) has the following variable: iprec0Powerfpidprocesses 0 (the fork function returns 0 in the child process)

For (iPendic0 pid_t fpid=fork (); / / completion of execution, iPIDBENT0 if (fpid==0) printf ("% d child% 4d% 4d% 4d/n", getpid (), fpid); else printf ("% d parent% 4d% 4d% 4d/n", iQuery getppid (), getpid (), fpid);} return 0; so print out the result:

0 parent 2043 3224 3225 0 child 3224 3225 0

The second step: assume that the parent process p3224 executes first, when entering the next loop, iNo.1, then execute fork, and a new process p3226 is added to the system. For the parent process at this time, p2043-> p3224 (current process)-> p3226 (the created child process).

For the child process p3225, after the first loop is executed, iComple1 is followed by fork, and a new process p3227 is added to the system. For this process, p3224-> p3225 (current process)-> p3227 (the created child process). From the output, we can see that p3225 was originally a child of p3224, but now it has become the parent process of p3227. Father and son are relative, which should be easy for everyone to understand. As long as the current process executes fork, the process becomes the parent and the parent is printed.

So the printed result is:

1 parent 2043 3224 3226 1 parent 3224 3225 3227

Step 3: step 2 creates two processes, p3226 and p3227, which end after executing the printf function, because the two processes cannot enter the third loop and cannot fork, so it is time to execute return 0; the same is true of other processes.

The following is the printed result of p3226 and p3227:

1 child 1 3227 0 1 child 1 3226 0

Careful readers may have noticed that the parent processes of p3226 recorder p3227 should not be p3224 and p3225, but how could it be 1? Here we talk about the process of creating and dying the process. After p3224 and p3225 execute the second loop, the main function should exit, that is, the process should die, because it has done everything. After the death of p3224 and p3225, p3226 and p3227 have no parent process, which is not allowed in the operating system, so the parent process of p3226 p3227 is set to p1, and p1 will never die. As for why, let's not introduce it here and leave it to "third, fork higher-level knowledge".

To sum up, the process that this program executes is as follows:

This program eventually produces three child processes and executes the printf () function six times.

Let's look at another piece of code:

/ * * fork_test.c * version 3 * Created on: 2010-5-29 * Author: wangth * / # include # include int main (void) {int iTuno; for (iTuno pid_t fpid=fork (); if (fpid==0) printf ("son/n"); else printf ("father/n");} return 0;} the result of its execution is:

Father son father father father father son son father son son son father son

I will not explain it in detail here, but only make a general analysis.

Each line represents the running print result of a process.

To sum up the rule, in the case of N cycles, the number of times to execute the printf function is 2 (1-2-4 +). + 2N-1) times, and the number of child processes created is 1 / 2 / 4 +. + 2N-1.

Some people on the Internet say that N cycles produce 2 * (1-2-4 +). + 2N) process, this statement is not true, I hope you should pay attention to it.

At the same time, if you want to test how many sub-processes have been created in a program, the best way is to call the printf function to print the pid of the process, that is, to call printf ("% dap", getpid ()), or through printf ("+ / n"); to determine how many processes have been generated. It is inappropriate for someone to count how many processes have been created by calling printf ("+");. I'll analyze the specific reasons.

Old rule, let's take a look at the following code:

/ * * fork_test.c * version 4 * Created on: 2010-5-29 * Author: wangth * / # include # include int main () {pid_t fpid;//fpid represents the value returned by the fork function / / printf ("fork!"); printf ("forkboat Ocean"); fpid = fork (); if (fpid printf ("error in fork!") Else if (fpid = = 0) printf ("I am the child process, my process id is% DZone", getpid ()); else printf ("I am the parent process, my process id is% DZone", getpid ()); return 0;} the execution result is as follows:

Fork! I am the parent process, my process id is 3361 I am the child process, my process id is 3362

If you comment out the statement printf ("forkboat Asia") and execute printf ("fork!"), the execution result of the new program is:

* Forbidden I am the parent process, my process id is 3298 Fortune I am the child process, my process id is 3299 *

The only difference in the program is a / n carriage return symbol. Why is the result so different?

This has something to do with the buffering mechanism of printf. When printf something, the operating system just puts it in the buffer queue of stdout and does not actually write it to the screen. However, the stdout will be refreshed as soon as you see / n, so you can print immediately.

Printf ("fork!") was run Later, "fork!" Just put in the buffer, the "fork!" in the buffer when the program runs to fork. The quilt process has been copied. So there is fork! in the sub-level stdout buffer. So, what you end up seeing is fork! Has been printf twice!

After running printf ("fork! / n"), "fork!" Is immediately printed to the screen, and then fork to the child process in the stdout buffer will not have fork! Content. So what you see will be fork! Printf once!

So printf ("+"); does not correctly reflect the number of processes.

You may be a little tired after reading so much, but I have to post the last piece of code to further analyze the fork function.

# include # include int main (int argc, char* argv []) {fork (); fork () & & fork () | | fork (); fork (); return 0;} the problem is how many processes the program has created, excluding the main process itself. In order to answer this question, let's cheat and use the program to verify how many processes there are.

# include int main (int argc, char* argv []) {fork (); fork () & & fork () | | fork (); fork (); printf ("+ / n");} the answer is a total of 20 processes, except for the main process, there are 19 processes.

Let's take a closer look at why there are still 19 processes. The first fork and the last fork will definitely be executed. Mainly on the middle 3 fork, you can draw a diagram to describe it. You need to pay attention to the & & and | | operators here. If An is not zero, it is not necessary to continue with & & B. if An is not 0, it is necessary to continue with & & B. A | | B, if An is not 0, there is no need to continue execution | | B, if not 0, you need to continue execution | | B.

The return values of fork () are different for parent and child processes, and five branches can be obtained by drawing according to the branches of parent B and A | | B above.

With the previous fork and the last fork, there are altogether 4-5-20 processes. Excluding the main process, there are 19 processes.

The above is the specific use of the fork function in the Linux system. Have you learned the knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report