新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 进程控制开发之:Linux进程控制编程

进程控制开发之:Linux进程控制编程

作者:时间:2013-09-13来源:网络收藏

本文引用地址:http://www.eepw.com.cn/article/257131.htm

3.exit()和_exit()

(1)exit()和_exit()说明。

exit()和_exit()都是用来终止进程的。当程序执行到exit()或_exit()时,进程会无条件地停止剩下的所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。但是,这两个还是有区别的,这两个函数的调用过程如图7.4所示。

图7.4exit和_exit函数流程图

从图中可以看出,_exit()函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据结构;exit()函数则在这些基础上做了一些包装,在执行退出之前加了若干道工序。exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的“清理I/O缓冲”一项。

由于在的标准函数库中,有一种被称作“缓冲I/O(bufferedI/O)”操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续读出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区中读取;同样,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(如达到一定数量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。

这种技术大大增加了文件读写的速度,但也为编程带来了一些麻烦。比如有些数据,认为已经被写入文件中,实际上因为没有满足特定的条件,它们还只是被保存在缓冲区内,这时用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失。因此,若想保证数据的完整性,就一定要使用exit()函数。

(2)exit()和_exit()函数语法。

表7.5列出了exit()和_exit()函数的语法规范。

表7.5 exit()和_exit()函数族语法

所需头文件

exit:#includestdlib.h>

_exit:#includeunistd.h>

函数原型

exit:voidexit(intstatus)

_exit:void_exit(intstatus)

函数传入值

status是一个整型的参数,可以利用这个参数传递进程结束时的状态。一般来说,0表示正常结束;其他的数值表示出现了错误,进程非正常结束。
在实际编程时,可以用wait()系统调用接收子进程的返回值,从而针对不同的情况进行不同的处理

(3)exit()和_exit()使用实例。

这两个示例比较了exit()和_exit()两个函数的区别。由于printf()函数使用的是缓冲I/O方式,该函数在遇到“n”换行符时自动从缓冲区中将记录读出。示例中就是利用这个性质来进行比较的。以下是示例1的代码:

/*exit.c*/

#includestdio.h>

#includestdlib.h>

intmain()

{

printf(Usingexit...n);

printf(Thisisthecontentinbuffer);

exit(0);

}

$./exit

Usingexit...

Thisisthecontentinbuffer$

读者从输出的结果中可以看到,调用exit()函数时,缓冲区中的记录也能正常输出。

以下是示例2的代码:

/*_exit.c*/

#includestdio.h>

#includeunistd.h>

intmain()

{

printf(Using_exit...n);

printf(Thisisthecontentinbuffer);/*加上回车符之后结果又如何*/

_exit(0);

}

$./_exit

Using_exit...

$

读者从最后的结果中可以看到,调用_exit()函数无法输出缓冲区中的记录。

小知识

在一个进程调用了exit()之后,该进程并不会立刻完全消失,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。

4.wait()和waitpid()

(1)wait()和waitpid()函数说明。

wait()函数是用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束,则wait()就会立即返回。

waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的wait()功能,也能支持作业控制。实际上wait()函数只是waitpid()函数的一个特例,在内部实现wait()函数时直接调用的就是waitpid()函数。

(2)wait()和waitpid()函数格式说明。

表7.6列出了wait()函数的语法规范。

表7.6 wait()函数族语法

所需头文件

#includesys/types.h>
#includesys/wait.h>

函数原型

pid_twait(int*status)

函数传入值

这里的status是一个整型指针,是该子进程退出时的状态
·status若不为空,则通过它可以获得子进程的结束状态
另外,子进程的结束状态可由中一些特定的宏来测定

函数返回值

成功:已结束运行的子进程的进程号
失败:-1

表7.7列出了waitpid()函数的语法规范。

表7.7 waitpid()函数语法

所需头文件

#includesys/types.h>
#includesys/wait.h>

函数原型

pid_twaitpid(pid_tpid,int*status,intoptions)

续表

函数传入值

Pid

pid>0:只等待进程ID等于pid的子进程,不管已经有其他子进程运行结束退出了,只要指定的子进程还没有结束,waitpid()就会一直等下去

pid=-1:等待任何一个子进程退出,此时和wait()作用一样

pid=0:等待其组ID等于调用进程的组ID的任一子进程

pid-1:等待其组ID等于pid的绝对值的任一子进程

status

同wait()

options

WNOHANG:若由pid指定的子进程不立即可用,则waitpid()不阻塞,此时返回值为0

WUNTRACED:若实现某支持作业控制,则由pid指定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态

0:同wait(),阻塞父进程,等待子进程退出

函数返回值

正常:已经结束运行的子进程的进程号

使用选项WNOHANG且没有子进程退出:0

调用出错:-1

linux操作系统文章专题:linux操作系统详解(linux不再难懂)


评论


相关推荐

技术专区

关闭