进程的生命周期

1. 进程创建

  由fork()创建进程。在之前所学的知识中可知,PID=0的进程(创建init之后,该进程成为了空闲进程)创建了init(PID=1)进程,而init进程是所有进程的父进程。在一个进程中,fork函数被正确调用之后,将会在子进程和父进程中分别返回;在子进程中返回0(不合法的PID);在父进程中返回子进程PID。

2. 进程启动

  在Linux下使用C语言开发应用,C程序的启动函数时main,进程的启动也时从main函数入口。

3. 进程状态切换

  进程被cpu调度的时候,进程在不同的状态之间切换,在Linux系统中,进程的状态有5种。

4. 进程终止

  • 正常终止
    • 从main返回、在任意代码中执行exit函数或者_exit函数、最后一个线程从其启动例程中返回、最后一个线程调用pthread_exit函数
  • 异常终止
    • 在任意代码中调用abort函数

  由下图可以看出,当调用 exit 函数的时候,会执行一系列的操作之后,再返回内核;而调用 _exit 函数之后,会直接返回内核。

  • exit和_exit均会正常终止一个进程
  • _exit:直接返回内核
  • exit:
    • 执行预先注册的终止处理函数
    • 执行文件I/O操作的善后工作,使得所有缓冲的输出数据被更新到相应的设备
    • 返回内核

进程的生命周期

return和exit的区别

  • return在终止函数的功能上和exit的相同
  • 在子函数中,return返回上一层函数;而exit终止进程。

注册终止处理函数

  由于我们不知道程序什么时候或者什么情况下会被终止,所以需要一个***制,用来注册终止注册函数,当程序终止的时候,会自动调用终止注册函数来对程序做善后处理。
  当执行exit之后,会首先调用终止处理函数。因为当一个进程执行完毕之后,程序需要释放、日志清理等工作,通过atexit函数或者on_exit函数,允许进程注册若干终止处理函数,当进程终止时,这些终止注册函数会被自动调用。

atexit和on_exit

  • atexit和on_exit的区别在于后者可以传递参数
  • 所有先被注册的函数,最后被回调

进程的生命周期

atexit() 示例代码及执行结果
进程的生命周期

on_exit()示例代码及结果
进程的生命周期