进程控制开发之:Linux进程控制编程
图7.4所示。
图7.4 exit和_exit函数流程图
从图中可以看出,_exit()函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据结构;exit()函数则在这些基础上做了一些包装,在执行退出之前加了若干道工序。exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的"清理I/O缓冲"一项。
由于在Linux的标准函数库中,有一种被称作"缓冲I/O(buffered I/O)"操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续读出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区中读取;同样,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(如达到一定数量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。
这种技术大大增加了文件读写的速度,但也为编程带来了一些麻烦。比如有些数据,认为已经被写入文件中,实际上因为没有满足特定的条件,它们还只是被保存在缓冲区内,这时用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失。因此,若想保证数据的完整性,就一定要使用exit()函数。
(2)exit()和_exit()函数语法。
表7.5列出了exit()和_exit()函数的语法规范。
表7.5 exit()和_exit()函数族语法
所需头文件 | exit:#include <stdlib.h> |
_exit:#include <unistd.h> | |
函数原型 | exit:void exit(int status) |
_exit:void _exit(int status) | |
函数传入值 | status是一个整型的参数,可以利用这个参数传递进程结束时的状态。一般来说,0表示正常结束;其他的数值表示出现了错误,进程非正常结束。 |
(3)exit()和_exit()使用实例。
这两个示例比较了exit()和_exit()两个函数的区别。由于printf()函数使用的是缓冲I/O方式,该函数在遇到"\n"换行符时自动从缓冲区中将记录读出。示例中就是利用这个性质来进行比较的。以下是示例1的代码:
/* exit.c */
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Using exit...\n");
printf("This is the content in buffer");
exit(0);
}
$./exit
Using exit...
This is the content in buffer $
读者从输出的结果中可以看到,调用exit()函数时,缓冲区中的记录也能正常输出。
以下是示例2的代码:
/* _exit.c */
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("Using _exit...\n");
printf("This is the content in buffer"); /* 加上回车符之后结果又如何 */
_exit(0);
}
$ ./_exit
Using _exit...
$
读者从最后的结果中可以看到,调用_exit()函数无法输出缓冲区中的记录。
小知识 | 在一个进程调用了exit()之后,该进程并不会立刻完全消失,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。 |
4.wait()和waitpid()
(1)wait()和waitpid()函数说明。
wait()函数是用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束,则wait()就会立即返回。
waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的wait()功能,也能支持作业控制。实际上wait()函数只是waitpid()函数的一个特例,在Linux内部实现wait()函数时直接调用的就是waitpid()函数。
(2)wait()和waitpid()函数格式说明。
表7.6列出了wait()函数的语法规范。
表7.6 wait()函数族语法
所需头文件 | #include <sys/types.h> |
函数原型 | pid_t wait(int *status) |
函数传入值 | 这里的status是一个整型指针,是该子进程退出时的状态 |
进程控制 Linux fork() 函数 操作系统 相关文章:
- 进程控制开发之:Linux进程概述(08-13)
- 进程控制开发之:Linux守护进程(08-13)
- 进程控制开发之:实验内容(08-13)
- REDIce-Linux--灵活的实时Linux内核(11-12)
- linux文件系统基础(02-09)
- Linux标准趋向统一(11-12)