免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3961 | 回复: 8
打印 上一主题 下一主题

父进程调用wait后,能否在子进程结束前由子进程通过kill命令唤醒 [复制链接]

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-24 21:37 |只看该作者 |倒序浏览
父进程通常使用wait来等待子进程的结束后再执行,但是我这里希望父进程等待子进程修改了某个变量后,再通知父进程继续运行,而子进程并不退出
即我希望如下代码能正确工作:
---------------------------------------------------------------

父进程                  子进程
...                                  ...
wait(&ret);                    kill(getppid(), SIGCONT);
do_something;              while(1){
                                          ...
                                      }
---------------------------------------------------------------
子进程通过kill向父进程发送SIGCONT消息后, 能够让父进程继续执行do_something,能实现吗?我试了下好像不行,请各位能指点下

论坛徽章:
0
2 [报告]
发表于 2009-05-24 23:03 |只看该作者
wait()你应该是用阻塞型的  
在一个死循环里,如果用waitpid()非阻塞型 应该是可以获得子进程的信号
来判断子进程到底发了什么信号,如果信号符合就退出死循环,主进程就执行下面的代码了
记不太清楚了  希望对你有帮助

论坛徽章:
0
3 [报告]
发表于 2009-05-24 23:16 |只看该作者
那用信号 试试------------signal

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
4 [报告]
发表于 2009-05-25 20:37 |只看该作者

回复 #3 lsupper 的帖子

我改为信号方式后,还是有问题,具体代码如下,程序运行的结果是有时子进程kill发出的消息能让父进程在pause后被唤醒,正确实现了父子进程同步的要求,如下显示:

-----------------------------------------
[admin@localhost signal]$ ./synsignal
child is going to send a signal.
in parent, begin to pause...
child is sleeping for 2 seconds.
signal is handled
parent wakes up now
-----------------------------------------

但是大多数情况下都是如下显示信息, 没有达到预期结果,父进程一直处于pause状态。是否有可行的其他办法让子进程通知父进程可以继续执行呢?
-----------------------------------------------
[admin@localhost signal]$ ./synsignal
child is going to send a signal.
child is sleeping for 2 seconds.
signal is handled
in parent, begin to pause...
child is sleeping for 2 seconds.
child is sleeping for 2 seconds.
。。。
-----------------------------------------------

问题代码如下:

19 #include <unistd.h>
20 #include <signal.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 void sig_handler(int sig)
27 {
28     printf("signal is handled\n");
29     return;
30 }
31
32 int main()
33 {
34     pid_t pid;
35     (void)signal(SIGCONT, sig_handler);
36     pid=fork();
37
38     switch(pid){
39         case -1:
40             perror("fork error!");
41             exit(1);
42         case 0:
43             printf("child is going to send a signal.\n");
44             kill(getppid(), SIGCONT); // 向父进程发消息

45             while(1){ // 这里故意用了死循环让子进程不结束
46                 printf("child is sleeping for 2 seconds.\n");
47                 sleep(2);
48                 /*kill(getppid(), SIGCONT);*/
49             };
50         default:
51             printf("in parent, begin to pause...\n");
52             pause(); // 此句执行前若已经处理了该signal,则没有办法再唤醒父进程了
53             printf("parent wakes up now\n");
54             break;
55     }
56     (void)signal(SIGCONT, SIG_DFL);
57     return 0;
58 }

[ 本帖最后由 jiufei19 于 2009-5-25 21:04 编辑 ]

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
5 [报告]
发表于 2009-05-26 10:28 |只看该作者

回复 #4 jiufei19 的帖子

自己仔细阅读了关于进程和信号部分的资料,发现了上述问题是必然的,因为当子进程首先被调度时,子进程向父进程发送了kill消息,然后子进程进入while循环中的sleep,此时父进程得到机会运行,这时父进程代码从switch开始执行,当此时收到kill发来的消息后,立刻执行消息处理程序sig_handler,接着再执行后续代码,那么当然后面的pause就无法被刚才已经执行的消息唤醒了

论坛徽章:
0
6 [报告]
发表于 2009-05-27 00:33 |只看该作者
很简单, 就是可能在主进程执行到 pause() 之前就已经得到信号并处理掉了...

应该先屏蔽信号再用sigsuspend()来实现

论坛徽章:
0
7 [报告]
发表于 2009-05-27 01:04 |只看该作者
用其它的方式实现进程间通信吧

老实说,信号现在用得不多了,一般只有内核需要通知进程才必须使用信号

论坛徽章:
0
8 [报告]
发表于 2009-05-27 01:50 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
9 [报告]
发表于 2009-05-27 13:49 |只看该作者
非常感谢各位的热心答复
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP