c - Waitpid 就像在非阻塞模式下一样
问题描述
我正在玩 C 中的系统调用,我一直试图理解我制作的这个程序 -
int main(int argc, char* argv[])
{
int a;
char *args[]={"sleep"," 10",NULL};
a = fork();
int stat;
if(a==0){
setpgid(getpid(),getpid());
printf("%d\n",getpgid(getpid()));
execvp(args[0],args);}
else
{
int t2;
waitpid(-a,&t2,0);
}
printf("Parent pid = %d\n", getpid());
printf("Child pid = %d\n", a);
}
据我了解,我已经将child的pgid设置为自己的pid。当我waitpid
使用 -a 作为参数调用时,我基本上要求它等待(阻塞)直到 pgid=a 中的任何进程完成。然而,程序的输出并不是我所期望的!子进程根本没有被收割。就好像 waitpid 处于非阻塞模式一样。输出:
Parent pid = 11372
Child pid = 11373
11373
(输出是瞬时的,它不会等待 10 秒!)
编辑:我在 execvp 下方添加printf("Here")
并exit(1)
打印出 waitpid 的输出,如评论中所建议的那样。这里没有打印,waitpid 打印 -1
解决方案
问题是竞争条件。在此处分叉后:
a = fork();
如果孩子首先运行,-a
则在此处创建进程组:
if(a==0){
setpgid(getpid(),getpid());
然后父母在这里等待:
waitpid(-a,&t2,0);
但如果父进程首先运行,则进程组-a
还不存在,并且waitpid()
失败并显示ECHILD
. 第二种情况显然发生在您的系统上。
您必须找到某种方法来确保子调用在父调用之前setpgid()
运行。复杂的方式是信号量,简单的(hacky)方式是短暂的延迟,然后可能就足够了。waitpid()
usleep(1)
waitpid()
推荐阅读
- cordova - 任务 ':app:processDebugGoogleServices' 执行失败,寻找 google-services.json 并没有成功找到它
- mysql - 如何将查询产生的表连接到存储在 mysql 上的过程的另一个临时表中?
- android - 设置中的Android“语音输入”选项丢失
- javascript - 基于嵌套属性过滤数组
- php - 我的 php 文件中的错误我似乎找不到?也许是由ajax引起的?
- python - Pandas:在检查另一列的成员资格时创建 NaN?
- c - C 冒泡排序最大的值变成0
- javascript - 减少 setState 中的计数器
- sql - 使用 SQL 创建 ID X-ref 表
- r - 如何使用 dplyr 将变量从数字转换为具有唯一级别的因子