In the Linux kernel, processes are maintained all the time, and every environment has complex details from process creation to process destruction. This article describes how processes are created in the Linux kernel. An in-depth understanding of the fork function and child process creation is also crucial to understanding multi-process development.

Fork () function

Let’s start with the fork() function, which creates child processes. The header file and function prototype are shown below

#include <unistd.h>

// Argument: void
// Returned value: pid_t ID of the created child process
pid_t fork(void);
Copy the code

Return value: fork() returns the value twice, one in the parent and one in the child.

  1. Returns the ID of the child in the parent process and 0 in the child process. So you can go throughforkTo distinguish the parent from the child process.
  2. Returns in the parent process- 1“, indicating that the sub-process fails to be created and the setting is specifiederrorno. The creation fails in the following two cases:
  • The number of processes in the system has reached the upper limiterrnoIs set toEAGAIN
  • The system is out of memoryerrnoIs set toENOMEM

Fork () example

Let’s create a child process to illustrate the order in which the parent and child processes execute.

#include <unistd.h>
#include <stdio.h>


int main(a){
	// Create process
	pid_t pid = fork();

	// Determine whether the current process is a parent or child process
	if (pid > 0) {// Process ID > 0 is the process ID of the child process. The current process is the parent process
		printf("pid: %d\n", pid);
		printf("I am parent process, pid: %d, ppid: %d\n", getpid(), getppid());
	}
	else if (pid == 0) {// Process ID == 0, which indicates that the current process is a child process
		printf("I am child process, pid: %d, ppid: %d\n", getpid(), getppid());
	}
	
	for (int i = 0; i < 5; i++){
		printf("pid: %d, i : %d\n", getpid(), i);
        sleep(1);
	}
	return 0;
}
Copy the code

The parent process ID is 412552, and the child process ID is 512553. The function is blocked due to sleep(), so the parent process and child process are executed alternately.

The virtual address space of the parent process

After creating a process through the fork function, you can determine whether it is a parent or child process by the return value. As for how the parent and child process execute, here is how the parent process executes after the fork call and how it is represented in the virtual address space of the process.

First, let’s look at the order of execution in the above example. After the parent process executes fork, the child process ID is returned.pidGreater than 0, so the outputif(pid>0)The content of the.

After the child process is successfully created, it returns 0 in the child process, starting from the current position, sopid=0Will be outputelseStatements.

For virtual space addresses, the child copies the parent’s virtual address space. Therefore, after fork, the child’s user area will be the same as the parent’s user area and will copy the contents of the kernel area, only the PID of the process will be different.

Variables in the stack space of the parent process are also copied to the stack space of the child process. However, the two variables do not affect each other, and the change of the parent variable does not affect the child variable. See the following program to show the use of stack space variables in a parent process.

#include <unistd.h>
#include <stdio.h>


int main(a){
	// Create process
	pid_t pid = fork();

	// Local variables
	int num = 10;

	// Determine whether the current process is a parent or child process
	if (pid > 0) {// Process ID > 0 is the process ID of the child process. The current process is the parent process
		printf("I am parent process, pid: %d, ppid: %d\n", getpid(), getppid());

		printf("parent process num : %d\n", num);
		num += 10;
		printf("parent process num + 10 : %d\n", num);

	}
	else if (pid == 0) {// Process ID == 0, which indicates that the current process is a child process
		printf("I am child process, pid: %d, ppid: %d\n", getpid(), getppid());

		printf("child process num : %d\n", num);
		num += 100;
		printf("child process num + 100 : %d\n", num);
	}
	
	return 0;
}
Copy the code

Compile and execute, as you can see, local variables in the parent processnumDoes not affect the local variables of the child process.   

Share while reading, copy while writing

In fact, Linux fork is precisely implemented by copy-on-write. Copy-on-write is a technique that can be delayed or even avoided. More specifically, the execution of the fork after the statement, the kernel is not to copy the address space of the parent, but the father and son to share the address space of the parent (as for a parent and child process address space is read only instruction), the parent or the child to write instructions, a copy of the child process will address space, so as to make the process of father and son have its own virtual address space, Write operations in its own address space. That is, resources are copied only when they need to be written, and before that, they are shared only in read-only mode.

For file resources, the parent and child processes share files after fork. The parent and child processes point to the same file table after fork, increase the reference count, and share the file offset pointer.


This article introduces the process of creating child processes and understanding the sharing and copying of virtual address Spaces between parent and child processes. In multithreaded development, it is easy to analyze the execution order and memory sharing of parent and child processes.

One key three link is my biggest encouragement and support, welcome to pay attention to programming town, every day up a little new posture 😄.