关于linux c的wait(int *status)函数

上操作系统课的时候,老师举例linux进程时说了wait函数,当时老师说wait(args)函数里面的参数的意思是等待指定时间,过了这个时间之后就不等待了。起初也没什么异议,因为我知道java的线程里面wait()确实是这样用的。但是今天编了一点程序,就发现完全不是这样的。

我编了这么一个程序:

 

那么,如果wait(2)的意思真的是等待3秒的话,在child wakes up语句执行之前,parent应该会被唤醒。但是事实并非如此,在子进程完全执行完毕之后,父进程才被唤醒,而且s的值是-1,也就是失败的意思。

然后看了wait()函数的说明,发现确实里面的参数完全不是等待时间,而是一个int型指针。所以,wait(3)这样的调用根本是不对的。

在此,我发现了一个linux C语言很奇怪的现象,wait函数明明是在<sys/wait.h>里面,但是我根本没有include它,却居然也能用。只不过编译的时候会出现|warning: implicit declaration of function ‘wait’|。也就是说,编译器会自动的隐式的把这个头文件给include进去。这样编译器看起来很智能,可惜编译器智能的还不够,因为它之后就忘了检查函数的参数类型了。于是wait(3)这样的语句居然就通过编译了,而且显然调用是出错的,返回值是-1.

于是我把#include<sys/wait.h>显式地写在文件里,一编译,wait(3)马上报错,参数不对。恩。这个应该是c语言编译器的问题了。

那么wait(int *status)的参数到底是什么呢?经过我查阅资料,大致认为是这样的:

wait()函数应该会返回两个东西,一个是子进程的pid,另外是子进程退出的时候的状态。由于return只可能出一个值,所以另外一个值得通过指针参数对外部变量值修改,由这个status外部变量体现出子进程退出的状态。

比如我子进程是正常退出,而且退出的时候运行的是exit(5).那么在父进程中,有这么一段话:

 

这样,c_pid就等于子进程的id,status是对应于子进程执行exit(5)后的一个值,这个值不是5,因为它不仅要返回exit的值,而且要返回是正常退出还是非正常退出。

从status中,可以判断出很多东西,当然不许要自己判断。linux提供了8个宏来判断这个status代表的意思。

比如要知道子进程exit()的值,就要用WEXITSTATUS(status)这个宏。

接着上面:

 

最后给出完整的测试程序:

 

 

另外,实验书上,有wait(0);这样调用的。这样调用是对的,等同于wait(NULL);,但是wait(非0数)一定是错的。

 

 

 

3 Comments

  • bachue

    2010 年 10 月 02 日 at 16:15 Reply

    这个问题我当天也发现了,之前输入某些输入都获取-1让我不解,后来确定赵正德讲错了。但是关于wait不用也能用的问题,我认为wait函数可能不止一个,我当时甚至还为此发过一个错误的推,后来删了,现在没找到,反正当时是找到了他的头文件。

  • iPhjyOOSe7en

    2010 年 10 月 03 日 at 01:01 Reply

    哎哟。。。这个blog的代码高亮是舒服啊

    要是baidu空间也有代码高亮就好了

  • bachue

    2010 年 10 月 03 日 at 02:21 Reply

    @iPhjyOOSe7en 那就不要用百度了

Post a Comment