CSAPP–第八章–异常(下)

Aki 发布于 2023-01-11 168 次阅读


创建和终止进程

程序是一段代码和数据,以文件形式存储在磁盘上的。进程是正在执行中程序的一个具体实例,在执行过程中是以段的形式存储在内存的地址空间中。

从程序员角度来看,可以认为进程总是处于下面三种状态之一:

  1. 运行:要么在CPU上执行,要么在等待被执行且最终会被操作系统内核调度(选中去运行)。
  2. 停止:被挂起,且不会被调度,直到收到信号SIGCONT(这是暂停,不是切换导致的)。
  3. 终止:进程永远地停止了。有三种原因:
    1. 收到一个信号,该信号默认行为是终止进程;
    2. 从主程序返回;
    3. 调用exit函数。

父进程通过fork()函数来创建一个新的运行的子进程。exit()函数以status退出状态来终止进程。

正常调用函数只会返回一次,然而函数fork调用一次却返回两次,一次返回到父进程,另外一次返回到新创建的子进程。

新创建的子进程几乎但不完全与父进程相同:

  • 子进程得到与父进程虚拟地址空间相同但独立的一份副本;
  • 子进程获得与父进程任何打开文件描述符相同的副本;
  • 子进程与父进程的PID不同。

fork函数特点:

  • 被调用一次,但返回两次:在父进程中返回子进程的PID;在子进程中返回0。这样就能够分辨父子进程了。
  • 父子进程并发执行:不能预测两者的执行顺序。
  • 相同但是独立的地址空间。
  • 共享打开的文件。

我们可以通过进程图来刻画fork函数:

#include<sys/types.h>  //linux下头文件
#include<unistd.h>     //linux下头文件
#include<iostream>
using namespace std;

 // pid_t fork(void);  fork函数的声明,pit_t实际上是int类型
 // getpid()  获取当前进程的pid
  
int main()
{
        pid_t p = fork();
        if (p == 0)
        {
	     cout << "child" << endl;
	     cout << "this pid = " << getpid() << endl;
        }
        else
        {
	     cout << "parent" << endl;
	     cout << "this pid = " << getpid() << endl;
        }
   
        return 0;
}