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()示例代码及结果