In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
What is the understanding of the FORK () function? I believe many inexperienced people are at a loss about it. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.
For people who are new to the Unix/Linux operating system and write multiple processes under Linux, fork is one of the most difficult concepts to understand: it executes once and returns two values.
First, let's look at the prototype of the fork function:
# i nclude
# i nclude
Pid_t fork (void)
Return value:
Negative: if something goes wrong, fork () returns-1, and no new process is created at this time. The original process is still running.
Zero: in a child process, fork () returns 0
Positive: in a negative process, fork () returns the PID of a positive child process.
Second, let's take a look at how to create child processes using fork.
The boilerplate code for creating a child process is as follows:
Pid_t child
If ((child = fork ()) 0)
{
Printf ("This is the parent process,the child has the pid:%d/n", pid)
}
Else if (! pid)
{
Printf ("This is the child process./n")
}
Else
{
Printf ("fork failed./n")
}
Printf ("This is third time, pid =% DAPO", pid)
Printf ("This is fouth time, pid =% DAPO", pid)
Return 0
}
The running results are as follows:
Question:
This result is very strange, why the printf statement is executed twice, while the "count++;" statement is executed only once
Go on to see:
# include
# include
Int main (void)
{
Pid_t pid
Int count=0
Pid = fork ()
Printf ("Now, the pid returned by calling fork () is% DAPO", pid)
If (pid > 0)
{
Printf ("This is the parent process,the child has the pid:%d/n", pid)
Printf ("In the parent process,count =% dzone", count)
}
Else if (! pid)
{
Printf ("This is the child process./n")
Printf ("Do your own things here./n")
Count + +
Printf ("In the child process, count =% DAPO", count)
}
Else
{
Printf ("fork failed./n")
}
Return 0
}
The running results are as follows:
Now let's explain the questions raised above.
When you look at this program, you must first understand a concept: before the statement pid=fork (), only one process is executing this code, but after this statement, it becomes two processes executing, the code parts of the two processes are exactly the same, and the next statement to be executed is if (pid > 0).
Of the two processes, the pre-existing one is called the "parent process", and the new one is called the "child process". In addition to the difference between parent and child processes, the value of the variable pid is also different in addition to the process identifier (process ID). Pid holds the return value of fork. 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 ID that created the new child process
two。 In a child process, fork returns 0
3. If an error occurs, fork returns a negative value
There may be two 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.
Let's take a look at the description of fork in APUE2:
The new process created by fork is called the child process. This function is called once but returns twice. The only difference in the returns is that the return value in the child is 0, whereas the return value in the parent is the process ID of the new child. The reason the child's process ID is returned to the parent is that a process can have more than one child, and there is no function that allows a process to o. Ain the process IDs of its children. The reason fork returns 0 to the child is that a process can have only a single parent, and the child can always call getppid to o ^ ain the process ID of its parent. (Process ID 0 is reserved for use by the kernel, so it's not possible for 0 to be the process ID of a child.)
A new process created by fork is called a self-process. The fork function is called once and returns twice. The only difference in the return value is that it returns 0 in the child process and the pid of the child process in the parent process. The reason to return the child's pid in the parent process is that the parent process may have more than one child process, and a process does not have any function to get the pid of its child process.
Both the child and the parent continue executing with the instruction that follows the call to fork. The child is a copy of the parent. For example, the child gets a copy of the parent's data space, heap, and stack. Note that this is a copy for the child; the parent and the child do not share these portions of memory. The parent and the child share the text segment (Section 7.6).
Both the child process and the parent process execute the code after the fork function call, and the child process is a copy of the parent process. For example, the data space and stack space of the parent process will give a copy to the child process instead of sharing the memory.
Current implementations don't perform. A complete copy of the parent's data, stack, and heap, since a fork is often followed by an exec. Instead, a technique called copy-on-write (COW) is used. These regions are shared by the parent and the child and have their protection changed by the kernel to read-only. If either process tries to modify these regions, the kernel then makes a copy of that piece of memory only, typically a "page" in a virtual memory system. Section 9.2 of Bach [1986] and Sections 5.6 and 5.7 of McKusick et al. [1996] provide more detail on this feature.
Let's give a detailed note.
# include
# include
Int main (void)
{
Pid_t pid
Int count=0
/ * here, the fork call is executed, creating a new process that shares the parent process's data, stack space, and so on, after which the code instruction creates a copy for the child process. The fock call is a copy process. Unlike the thread, fock needs to provide a function as the entry. After the fock call, the entry of the new process is in the next statement of fock. , /
Pid = fork ()
/ * the value of pid here indicates whether the parent process or the child process is being executed after the fork call * /
Printf ("Now, the pid returned by calling fork () is% DAPO", pid)
If (pid > 0)
{
/ * when fork returns in the child process, the fork call returns the pid of the child process to the parent process. If the code is executed, but note that the count is still 0, because the count in the parent process has never been reassigned, we can see that the data and stack space of the child process are independent of the parent process, rather than sharing data * /
Printf ("This is the parent process,the child has the pid:%d/n", pid)
Printf ("In the parent process,count =% dzone", count)
}
Else if (! pid)
{/ * add 1 to count in the child process, but it does not affect the count value in the parent process, which is still 0 percent /
Printf ("This is the child process./n")
Printf ("Do your own things here./n")
Count++
Printf ("In the child process, count =% DAPO", count)
}
Else
{
Printf ("fork failed./n")
}
Return 0
}
In other words, the next process in Linux has three parts of data in memory, namely, "code segment", "stack segment" and "data segment". " Code snippet ", as the name implies, is the storage of program code data, if there are several processes running the same program, then they can use the same code snippet." The stack segment stores the return address of the subroutine, the parameters of the subroutine, and the local variables of the program. Data segments store the program's global variables, constants, and data space for dynamic data allocation (such as those obtained by functions such as malloc). If the system runs several identical programs at the same time, the same stack segment and data segment cannot be used between them.
After careful analysis, we can know:
Once a program calls the fork function, the system prepares the above three segments for a new process. First, the system lets the new process use the same code segment as the old process, because their programs are still the same. For the data segment and stack segment, the system copies a copy to the new process, so that all the data of the parent process can be reserved for the child process, but once the child process starts running. Although it inherits all the data of the parent process, in fact the data is separate and no longer affects each other, that is, they no longer share any data.
Not only does fork () create a child process with the same code as the parent process, but all contextual scenarios of the parent process at the fork execution point are automatically copied to the child process, including:
-- Global and local variables
-- Open file handle
-- shared memory, messages and other synchronization objects
If the two processes want to share any data, they need to use another set of functions (shmget,shmat,shmdt, etc.) to operate. Now, there are two processes. For the parent process, the fork function returns the process number of the subroutine, while for the subroutine, the fork function returns zero, so that for the program, as long as you judge the return value of the fork function, you will know whether you are in the parent process or the child process.
After reading the above, have you mastered the method of understanding what the FORK () function is? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.