Linux操作系统关于进程的控制

文章目录

  • 一、✔进程创建
    • 1.再谈fork函数
    • 2.写时拷贝
  • 二、✔进程终止
    • 1.进程终止的场景
      • 查看进程退出码所代表的含义
    • 2.进程终止的常见方法
    • 3.进程终止,内核做了什么工作
  • 三、✔进程等待
    • 1.进程等待的必要性
    • 2.进程等待的方法
      • (1)wait方法
      • (2)waitpid方法
        • ①status
        • ②options
  • 四、✔进程程序替换
    • 1.什么是进程程序替换
    • 2.怎么进行进程程序替换
      • (1) execl
      • (2) execv
      • (3) execlp
      • (4) execvp
      • (5) execle
      • (6) 剩余的函数


一、✔进程创建

1.再谈fork函数

fork是Linux中非常重要的函数,它能够从已经存在的进程中创建一个新的进程,新创建的进程叫做子进程,原有的进程叫做父进程。
头文件:
返回值:子进程返回0,父进程返回子进程的pid,当子进程创建失败时返回-1

fork的具体介绍在上一篇博客里写了,可以点击链接查看

当我们的进程调用fork函数以后,内核会为我们做这几件事:

  • 分配新的内存块和内核数据结构给子进程(task_struct、mm_struct、页表)
  • 将父进程部分数据结构的内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork准备返回时,开始调度器调度

Linux操作系统关于进程的控制_第1张图片

所以,fork函数之前,父进程是独立执行的,fork函数之后,父进程和子进程两个执行流分别执行。
注意:fork之后,谁先执行完全由调度器决定

我们可以写一个简单的代码来简单地验证一下fork函数前后的变化:
Linux操作系统关于进程的控制_第2张图片

我们运行程序查看结果:
我们可以看到在fork函数之前,只有父进程一个进程在执行;在fork函数之后,父进程和子进程分别执行。
Linux操作系统关于进程的控制_第3张图片

fork函数创建子进程以后,子进程将共享父进程的代码,这里的共享父进程的代码虽然看起来像是子进程只共享父进程在fork函数之后的所有代码,但实际上子进程是共享父进程的所有代码。只不过子进程只能从fork函数之后开始执行。

为什么刚创建出的子进程就能够知道父进程的代码执行到哪里了呢?
答:原因是在CPU中有一种寄存器叫作eip(程序计数器),也有的地方叫作PC指针,这个寄存器能够保存进程当前正在执行指令的下一条指令。而当父进程创建出子进程以后,父进程的eip程序计数器会被拷贝给子进程,子进程便知道父进程接下来要执行的指令是什么了。

2.写时拷贝

在fork函数成功创建子进程后,通常情况下父子进程代码是共享的,如果父子进程都不写入或者修改数据的情况下,数据也是共享的。当任意一方试图写入或修改数据时,操作系统便以写时拷贝的方式拷贝一份副本。(具体见下图)

Linux操作系统关于进程的控制_第4张图片

为什么要有写时拷贝呢?难道不可以在创建子进程的时候就直接拷贝父进程的数据嘛?
答:在创建子进程的时候就把父子进程分开,这个方法是可以实现的。但是我们之所以不选择这个方法,是因为该方法并不是最优的。为什么要有写时拷贝,我们先来看看其他方案的缺点:

  1. 首先,如果在创建子进程的时候就将父子进程的数据分离开,父进程的数据子进程不一定会全部使用,即便全部使用了,也不一定全部写入,所以就会有浪费空间的可能性。
  2. 除此之外,最理想的方案是只将会被父子修改的数据进行分离拷贝,不需要修改的数据父子进程共享即可。但这种方案从技术角度实现复杂。

所以最终采用写时拷贝!也就是只有真正需要修改的时候才拷贝,这就是延迟拷贝策略。

二、✔进程终止

1.进程终止的场景

关于进程的终止,我们必须要有正确的认识,首先我们要回答下面的几个问题:在我们写代码的时候,main函数都会有一个返回值,我们一般返回值写的是0,那么这个返回值是给谁返回的?这个返回值为什么是0?可以是其他值嘛?

要回答上面的问题,我们首先来认识一下进程退出的场景:

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码异常终止

因此,我们每一个程序的main函数会有返回值,是因为在进程代码跑完的时候,父进程需要这个返回值来判断进程的运行结果,如果返回值是0,则表示代码跑完结果正确,非零则表示失败了。
这个返回值就是“进程退出码”!进程退出码表征了进程退出

你可能感兴趣的:(Linux系统编程,linux,服务器,运维,c语言,c++)