#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
函数的作用:用于创建子进程。
返回值:
fork()
的返回值会返回两次。一次是在父进程中,一次是在子进程中。
在父进程中返回创建的子进程的
ID,
在子进程中返回
0
如何区分父进程和子进程:通过
fork
的返回值。
在父进程中返回
-1
,表示创建子进程失败,并且设置
errno
父子进程之间的关系:
区别:
1.fork()
函数的返回值不同
父进程中
: >0
返回的子进程的
ID
子进程中
: =0
2.pcb
中的一些数据
当前的进程的
id pid
当前的进程的父进程的
id ppid
信号集
共同点:
某些状态下:子进程刚被创建出来,还没有执行任何的写数据的操作
-
用户区的数据
-
文件描述符表
父子进程对变量是不是共享的?
-
刚开始的时候,是一样的,共享的。如果修改了数据,不共享了。
-
读时共享(子进程被创建,两个进程没有做任何的写的操作),写时拷贝。
*/
实际上,更准确来说,Linux 的 fork() 使用是通过写时拷贝 (copy
on-write) 实现。写时拷贝是一种可以推迟甚至避免拷贝数 据的技术。内核此
时并不复制整个进程的地址空间,而是让父子进 程共享同一个地址空间。只用在
需要写入的时候才会复制地址空间 ,从而使各个进行拥有各自的地址空间。也就
是说,资源的复制是 在需要写入的时候才会进行,在此之前,只有以只读方式共
享。注意:fork 之后父子进程共享文件,fork 产生的子进程与父进程相同的文件
文件描述符指向相同的文件表,引用计数增加,共享文件偏移指针。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main() {int num = 10;
// 创建子进程
pid_t pid = fork(); //下面是父进程和子进程共有代码段。若想让他们执行不同的
代码,则通过 pid 号判断是父进程和子进程来执行不同的代码。
// 判断是父进程还是子进程
if(pid > 0) {
// printf("pid : %d\n", pid);
// 如果大于 0,返回的是创建的 子进程的进程号,当前是父进程
printf("i am parent process, pid : %d, ppid : %d\n", getpid(),
getppid());
//主进程的 ppid
是终端
printf("parent num : %d\n", num);
num += 10;
printf("parent num += 10 : %d\n", num);
} else if(pid == 0) {
// 如果等于 0 当前是子进程
printf("i am child process, pid : %d, ppid : %d\n",
getpid(),getppid());
printf("child num : %d\n", num);
num += 100;
printf("child num += 100 : %d\n", num);
}
// for 循环
for(int i = 0; i < 3; i++) {
printf("i : %d , pid : %d\n", i , getpid());
sleep(1);
}
return 0;
}
主进程的
ppid
是终端
,
pid
是
87634
子进程的
ppid
是
87634
,
pid
是
87635
int main() {
int num = 10;
// 创建子进程
pid_t pid = fork();
// 判断是父进程还是子进程
if(pid > 0) {
// printf("pid : %d\n", pid);
// 如果大于 0,返回的是创建的 子进程的进程号,当前是父进程
printf("i am parent process, pid : %d, ppid : %d\n", getpid(),
getppid());
//主进程的 ppid 是终端
printf("parent num : %d\n", num);
num += 10;
printf("parent num += 10 : %d\n", num);
}
// for 循环
for(int i = 0; i < 3; i++) {
printf("i : %d , pid : %d\n", i , getpid());
sleep(1);
}
return 0;
}
子进程执行的代码
else if(pid == 0) {
// 当前是子进程
printf("i am child process, pid : %d, ppid : %d\n",
getpid(),getppid());
printf("child num : %d\n", num);
num += 100;
printf("child num += 100 : %d\n", num);
}
// for 循环
for(int i = 0; i < 3; i++) {
printf("i : %d , pid : %d\n", i , getpid());
sleep(1);
}
return 0;
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main() {
// 创建一个子进程,在子进程中执行 exec 函数族中的函数
pid_t pid = fork();
if(pid > 0) {
// 父进程
printf("i am parent process, pid : %d\n",getpid());
sleep(1);
}else if(pid == 0) {// 子进程
// char* envp[] = {"/home/u/Desktop/Linux"};
// execle("/home/u/Desktop/Linux/hello", "hello", NULL, envp);
execl("/usr/bin/ps", "aux", NULL);
//子进程所有的代码会被替换掉,不会执行的
printf("i am child process, pid : %d\n", getpid());
}
for(int i = 0; i < 3; i++) {
printf("i = %d, pid = %d\n", i, getpid());
}
return 0;
}