1.什么是进程
一个进程相当于一个打开的应用程序,对于系统来说,分配资源是以进程为单位的。每个进程独享一个4g的空间,包括1g的内核区和3g的用户区,一个程序的所有资源都在这里面,包括堆栈,堆,文件描述符,函数表等。
2.多进程的意义
一个进程可以申请一批资源,多进程就可以申请更多的资源,同时每个进程独立执行任务,是并行的执行方式,使得资源的使用效率更高。试想一下,在一个公司中,一个人的精力是有限的,公司的资源也是有限的,而提高公司运作效率的方法自然是把资源尽可能分配完,招多个员工,每个员工执行充足量的任务,使得公司没有白分配的资源,把资源和人力都充分利用起来。这其中公司相当于一个系统,一个人相当于一个进程,多进程就是任务的分发执行的过程,可以大大提高任务执行的效率。

3.linux下多进程的特性
linux下进程的资源分配图如下:

以上是一个进程虚拟地址空间示意图,其中用户区占据3g,内核区占据1g。
为了保护硬盘,防止用户的不当操作导致的错误,进程并不是直接把物理地址映射到程序,而是创建一个虚拟进程,这个虚拟地址空间可能要远比实际的空间大,但是实际操作的时候是由系统去控制调度空间的,不会全部映射出来。否则一个进程4g,一个系统可能同时运行几千个进程,系统势必是没有那么大空间来供这么多进程一起运行的。
多进程下,创建新的子进程,新的进程和原有进程的堆栈和栈,代码区,环境变量,文件描述符等资源是一样的,基本按逻辑应该复制的资源都是相同的。
进程pid(区分进程的标识id,可以认为是系统给每个进程的名字)、闹钟alarm、未决信号集则是不一样的。
问题:系统需要复制父进程的资源吗?
答案是否!因为如果你要创建很多个进程,每个进程要4g空间,复制4个g非常不现实,既浪费空间也需要耗费时间复制。因此,创建出来的子进程遵循“用时共享,写时复制”的原则。
用时共享,写时复制
使用父进程创建的资源时,直接调用父进程的资源,当需要对父进程的资源进行修改或申请新的资源时,则复制父进程的资源或在子进程独立申请,这样就做到了高效率德恩利用资源,减少了无意义的复制。
4.linux下多进程代码
fork函数:创建子进程
// pid_t fork();
// 函数会创建新的进程
// 函数的返回值:
// 父进程:返回子进程pid(是整数类型)
// 子进程: 返回0
// 创建失败:返回-1
创建子进程流程:
// #include ...
// include的内容省略,需要的时候在linux的bash命令行终端下man + 空格 + 命令内容 查询即可
int main(int argc, char* argv[]) {
int i = 0;
const int P_NUM = 10; // 假设创建十个进程。
for (i = 0; i < P_NUM; ++i) {
pid_t pid = fork();
if (pid == -1) {
perror("fork err");
exit(1);
}
else if (pid == 0)
break;
}
if (i == P_NUM) {
// 父进程执行的代码
}
else {
// 每个子进程执行的代码
// 当然可以用更多的if,更细化的任务,如i == 1的子进程和i == 2的子进程执行不同的任务
// pid_t getpid()可以获取当前的进程的pid
// pid_t getppid()可以获取当前进程的父进程的pid
}
return 0;
}