前面文章我们介绍了PCB(进程控制块),进程和并发的概念,今天我们来介绍一下进程的控制原语(说白了就是怎么用进程)
在介绍之前我们先来个视频了解一下博主:
白嫖者vsup主
好,和大家认识之后,我们来 详细的介绍一下
一.fork函数(重点&基本)
1)pid_t fork(void);这个函数我们重点来说一说, 创建进程失败return -1, 在父进程中成功创建子进程(return 子进程的进程,以便父进程后面好通过进程号,来操作子进程),在子进程中(创建成功return 0);
2)我们来 说一说 这个函数具体做的工作(一幅图)
3)在来讨论一个问题,都说fork创建的子进程是父进程的完美复制,用户空间内存值完全一样,但是也有一些不一样的(内核空间)我们来讨论讨论
- 与子进程相同之处:全局变量,.data, .text, 堆,栈, 环境变量, 用户ID, 宿主目录, 进程工作目录, 信号处理方式
- 不同之处: 进程ID, fork返回值, 父进程ID, 进程运行时间, 闹钟(定时器), 未决信号集
这里看来子进程好像复制了父进程 0-3G用户空间的所有内容, 以及父进程的PCB, 但pid 不同,真的是完全copy一份 嘛?
其实 不是 的 操作系统提供了 优化,读共享,写独占(意思就是 子进程在访问一个变量之后,如果时 写,就从copy一份那个变量从父进程进行写, 如果只是读 就和 父进程共享那一份变量,提高了内存的利用率和 运行效率)
其他的函数 建议查linux提供的 man 文档手册,在打开有道字典,这个 世界就是你的了,哈哈哈
Demo代码
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
using namespace std;
int
main(int argc, char* argv[])
{
pid_t pid;
printf("---to start---\n");
pid = fork();
if(pid < 0){
perror("fork error");
exit(1);
}else if(pid == 0){
printf("I am child, my parent ID: %u, my ID: %u \n", getppid(), getpid());
}else{
sleep(1);
printf("I am parent, my parent ID: %u, my ID: %u \n", getppid(), getpid());
}
printf("xxxxxxx \n");
return 0;
}