PCB(进程描述符)位于内核空间中,每个进程的PCB是不同的,PCB是一个task_struct[1]结构体包括:
进程id。每个进程都有一个唯一id,类型为pid_t(非负整数)。
进程状态。就绪、运行、阻塞、停止。
进程切换时需要保存和恢复的CPU寄存器。
VM与PM的映射,由MMU转化,保存在PCB中。
当前工作目录。
umask掩码,提供文件权限相关。
文件描述符表。
信号相关信息。
用户id和组id。
…
FORK(2) Linux Programmer's Manual FORK(2)
NAME
fork - create a child process
SYNOPSIS
#include
pid_t fork(void);
DESCRIPTION
fork() creates a new process by duplicating the calling process. The new
process is referred to as the child process. The calling process is referred to
as the parent process.
RETURN VALUE
On success, the PID of the child process is returned in the parent, and 0 is
returned in the child. On failure, -1 is returned in the parent, no child
process is created, and errno is set appropriately.
返回值有两个,大于0代表父进程,等于0代表子进程(子进程成功被创建)。
#include
#include
#include
int main() {
pid_t pid;
printf("======before======\n");
pid = fork();
if (pid == -1) {
printf("fork error");
exit(1);
} else if (pid == 0) {
printf("===child, pid = %u, ppid = %u\n", getpid(), getppid());
} else {
printf("===parent, pid = %u, ppid = %u\n", getpid(), getppid());
sleep(1);
}
printf("======after======\n");
return 0;
}
~# ./test
======before======
===parent, pid = 9215, ppid = 8980
===child, pid = 9216, ppid = 9215
======after======
======after======
#include
#include
#include
int main() {
pid_t pid;
int n = 5;
printf("======before======\n");
int i;
for (i = 0; i < n; i++) {
pid = fork();
if (pid == -1) {
printf("fork error");
exit(1);
} else if (pid == 0) {
//printf("===child, pid = %u, ppid = %u\n", getpid(), getppid());
//如果是子进程的话,直接跳出循环~
break;
} else {
//只有父进程继续执行 创建子进程
}
}
if (i < n) {
printf("child %dth, pid = %u, ppid = %u\n", i + 1, getpid(), getppid());
}
return 0;
}
~# ./test
child 5th, pid = 9345, ppid = 1
child 4th, pid = 9344, ppid = 1
child 3th, pid = 9343, ppid = 1
child 2th, pid = 9342, ppid = 1
child 1th, pid = 9341, ppid = 1
刚fork之后
共享:全局变量、.data、.text、栈、堆、…
不共享:进程ID,fork返回值,父进程ID,进程运行时间,定时器,未决信号集。
fork之后
共享:文件描述符和mmap建立的映射区。
注意:全局变量也不会共享的。
父子进程遵循读时共享写时复制原则。
[1] https://elixir.bootlin.com/linux/v4.1.15/source/include/linux/sched.h#L1292