有时需要等待……
newshound2 程序启用独立的进程运行 rssgossip.py 脚本,而子进程一创建就和父进程没关系了。rssgossip.py 还没有完成任务,newshound2 程序就结束了,所以 stories.txt 还是空的。也就是说,操作系统必须提供一种方式,让你等待子进程完成任务。
waitpid() 函数
waitpid() 函数会等子进程结束以后才返回,也就是说可以在程序中加几行代码,让它等到 rssgossip.py 脚本运行结束以后才退出。
waitpid() 聚焦
waitpid() 接收三个参数:
pid
父进程在克隆子进程时会得到子进程的 ID。
pid_status
pid_status 用来保存进程的退出信息。因为 waitpid() 需要修改 pid_status ,因此它必须是个指针。
选项 waitpid() 有一些选项,详情可以输入 man waitpid 查看。如果把选项设为 0 ,函数将等待进程结束。什么是 pid_status?waitpid() 函数结束等待时会在 pid_status 中保存一个值,它告诉你进程的完成情况。为了得到子进程的退出状态,可以把 pid_status 的值传给 WEXITSTATUS() 宏:为什么要用宏来查看?因为 pid_status 中保存了好几条信息,只有前 8 位表示进程的退出状态,可以用宏来查看这 8 位的值。
试驾
运行 newshound2 程序,它会在退出前检查 rssgossip.py 脚本是否完成:
在程序中加入 waitpid() 很容易办到,它可以让代码更加可靠。而在此之前无法确定子进程是否已经写完了文件,也就是说 newshound2 并不是一个合格的工具,你无法在脚本中使用它,也无法为它创建界面。
重定向输入、输出,然后让进程相互等待,进程间通信就这么简单。一旦进程可以合作——通过共享数据和互相等待——它们将所向披靡。
要点
exit() 可以快速结束程序。
所有打开的文件都记录在描述符表中。
通过修改描述符表就可以重定向输入和输出。
fileno() 能在表中查找描述符。
dup2() 可以用来修改描述符表。
waitpid() 等待进程结束。
这里没有蠢问题问:用 exit() 来结束程序比从 main() 返回更快吗?答:不会。但如果你已经调用了 exit() ,就不需要想办法让代码再回到 main() 函数。在你调用 exit() 的一瞬间,程序就升天了。问:为了防止调用失败,调用 exit() 时需要检查它的返回值是否为-1 吗?答:不需要,exit() 不会失败,因此也就没有返回值。exit() 是唯一没有返回值而且不会失败的函数。问:传给 exit() 的那个数字是退出状态吗?答:是的。问:标准输入、标准输出和标准错误一定是描述符表的 0、1、2 号吗?答:一定。问:每当我打开一个新文件,它都会自动添加到描述符表中吗?答:没错。问:通常是几号描述符?答:新文件总是按序加入描述符表,如果第一个空的描述符是 4 号,你的文件就会用它。问:描述符表有多大?答:从 0 号到 255 号。问:描述符表那么麻烦,有必要用吗?答:当然有,不使用描述符表,就不能改变程序的工作方式,也就不能重定向。问:除了用标准输出,还有没有其他方法把数据发送到屏幕?答:在一些系统上,比如 Unix,如果打开/dev/tty 文件,就可以把数据直接发送到终端。问:我能用 waitpid() 等待其他进程吗?还是只有我启动的那些?答:你可以用 waitpid() 等待任何进程。问:为什么不能根据 wait_pid(..., &pid_status, ...) 中的 pid_status 直接判断退出状态?答:因为 pid_status 中还包含了其他信息。问:哪些信息?答:如果一个进程自然死亡,WIFSIGNALED(pid_status) 就为假,如果是他杀,WIFSIGNALED(pid_status) 就为真。问:pid_status 明明是整型变量,怎么可以包含多条信息?答:用不同的位来保存不同的信息。pid_status 的前 8 位保存了退出状态,而其他信息保存在了剩余那些位中。问:是不是只要自行提取出 pid_status 的前 8 位,就可以不用 WEXITSTATUS() ?答:最好还是用 WEXITSTATUS() ,它不但可以提高代码的可读性,而且无论 int 在你的平台上有多大,程序都能正确工作。问:为什么 WEXITSTATUS() 要大写?答:因为 WEXITSTATUS() 是宏,不是函数。编译器运行时会把宏替换为一小段代码。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论