守护进程和fork()以及管道通信的结合

yuhan1573 2009-05-08 04:12:24
描述得有点长,希望大家耐心地看完。。。

有这么一个结构:
进程A:调用了daemon()函数,脱壳成为守护进程。
然后调用fork()函数,执行execlp()开启一子进程B。此时父进程即A本身并没有退出,而是通过管道与子进程B通信(心跳检测)。
子进程B:随便一个可以长久运行的独立程序。其中包含了管道通信模块,即程序一旦开启,立即通过管道取得与进程A的通信。

实际上这个结构的目的就是:通过A来监控B。

现在的问题是:

单独运行A,即调用daemon()后,不调用fork(),execlp()开启子进程B.CPU利用率正常。
单独运行B,即不通过A来开启B。B的本身没有问题,正常。CPU利用率 2%左右。

通过A开启B,并通过管道通信。CPU利用率达100%!!!!

去除管道通信模块,即单纯地利用A开启B,CPU利用率仍100%!!!

A中去除daemon()函数,即以普通程序形态开启B,CPU利用率正常!添加管道通信模块也没什么影响。

先开启A程序(精灵形态,即包含daemon()函数),并开启通信模块。单独运行B,开启通信模块与A取得通信。CPU利用率也正常!

我是不是可以得出:在A的精灵形态中开启子进程B是有问题的(至少表现是这样!)

难道在一个精灵形态的进程中利用fork()开启另外一个子程序,对这个子进程有什么特别限制???因为A的精灵形态中开启另外一个子进程C却没这个问题!

谁能救救我????崩溃了都
...全文
338 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuhan1573 2009-05-13
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 guosha 的回复:]
strace跟一下试试。
[/Quote]

这东西没用过,用这个调试能查出来到底是程序中什么工作使CPU利用率达到100%吗?
yuhan1573 2009-05-13
  • 打赏
  • 举报
回复
重新理了下思路,问题可以归结为这样:

1.B程序单独运行没问题。
2.A在普通状态下开启B没问题。
3.A在精灵状态下开启B有问题(CPU利用率100%)。
4.A在精灵状态下开启C没问题。

利用strace -f 跟踪看了下,当程序进入长期稳定运行状态,会不停地进行系统调用gettimeofday(),nanosleep(),2情况表现正常,3则CPU利用率变高。
快乐田伯光 2009-05-12
  • 打赏
  • 举报
回复
strace跟一下试试。
yuhan1573 2009-05-12
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 hjy82919 的回复:]
我估计楼主管道未设置正确,导致管道出现死循环,以至CPU100%。本人曾写过相似的守护进程,在进程里调用Java虚拟机,并通过管道来通讯。
[/Quote]

我也曾怀疑过是管道的问题,可是经过测试排除了这一可能,具体测试例子我在一楼已经列举出来了,兄台可以帮忙看下。是否那组测试并不能说明问题。
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 yuhan1573 的回复:]
引用 6 楼 guosha 的回复:
楼主就是想AB都是守护进程吧?
引用 4 楼 hairetz 的回复:
楼主,换个顺序看下。
先fork出B,然后再使A成为守护进程。


说得明白点,程序B类似于FTP那种功能,长期运行于服务器上,提供给客户端连接。
我做了个监控程序A,让A,B通过管道通信,互相监测。如果A发现B停止运行,可以通过接受指令,重新fork开启B。如果B发现A停止运行,则结束自身。
因此,我希望服务器一启动的时候加载监…
[/Quote]

那你还顺序测了没?用管道通信就可以实现了啊
yuhan1573 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 sytu_hzj 的回复:]
你还不如用Socket来通信算了
[/Quote]
跟用什么通信好像没关系把。。。
libingwai 2009-05-11
  • 打赏
  • 举报
回复
用WAITPID的方式也可以吧,用管道写的是不是有点复杂了?
把代码拿来看看嘛
sytu_hzj 2009-05-11
  • 打赏
  • 举报
回复
你还不如用Socket来通信算了
paradise099 2009-05-11
  • 打赏
  • 举报
回复
我估计楼主管道未设置正确,导致管道出现死循环,以至CPU100%。本人曾写过相似的守护进程,在进程里调用Java虚拟机,并通过管道来通讯。
yuhan1573 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 guosha 的回复:]
楼主就是想AB都是守护进程吧?
引用 4 楼 hairetz 的回复:
楼主,换个顺序看下。
先fork出B,然后再使A成为守护进程。
[/Quote]

说得明白点,程序B类似于FTP那种功能,长期运行于服务器上,提供给客户端连接。
我做了个监控程序A,让A,B通过管道通信,互相监测。如果A发现B停止运行,可以通过接受指令,重新fork开启B。如果B发现A停止运行,则结束自身。
因此,我希望服务器一启动的时候加载监控程序A,故首先把它脱壳成为守护进程(不知道此步实现与目的是否合适?),等待接受指令开启B。
yuhan1573 2009-05-11
  • 打赏
  • 举报
回复
实际上我调用的参数是daemon(0,0)按照参数说明,系统应该是执行了chdir('/'),以及将stdin,stdout,stderr重定向到了dev/null。
yuhan1573 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 guosha 的回复:]
你程序B的log打印到什么地方去了?
[/Quote]

程序B运行之初会cout几行提示信息,A程序调用daemon()后再fork(),execlp()开启B,B的输出我也不知道到哪去了。不知道系统的daemon()函数会不会把输出重定向。。。
yuhan1573 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hairetz 的回复:]
那你还顺序测了没?用管道通信就可以实现了啊
[/Quote]

所有的功能模块都实现了的。就是精灵状态fork出B有问题,CPU利用率100%。跟管道通信没关系。

我没有换顺序测,不知道A先fork出B,再转换成精灵状态有什么作用,还有可能会有问题,即A开启B后,势必会通过管道与B取得通信,这时候再调用daemon转换形态,就会把原来打开的管道文件给关闭,造成无法继续通信。这就不是我想要的结果了。。
快乐田伯光 2009-05-10
  • 打赏
  • 举报
回复
楼主就是想AB都是守护进程吧?
[Quote=引用 4 楼 hairetz 的回复:]
楼主,换个顺序看下。
先fork出B,然后再使A成为守护进程。
[/Quote]
快乐田伯光 2009-05-10
  • 打赏
  • 举报
回复
你程序B的log打印到什么地方去了?
  • 打赏
  • 举报
回复
楼主,换个顺序看下。
先fork出B,然后再使A成为守护进程。
zhouxingyu896 2009-05-09
  • 打赏
  • 举报
回复

关注
yuhan1573 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 morris88 的回复:]
把代码贴上来...
[/Quote]

太长了。。。
morris88 2009-05-08
  • 打赏
  • 举报
回复
把代码贴上来...

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧