如何查询进程状态,进程异常退出时会有什么信号发出?如何捕获?

Cemondd 2006-12-07 10:13:05
遇到的问题是这样的,在正常情况下,进程A持续通过消息队列向进程B发送消息,而当进程B异常退出时,进程A并不知道.如何才能让进程A知道B已经退出,如果在程序中用"ps"来进行每次发送消息之前都查看B的状态的话,效率将非常慢.因为"ps"命令每次执行都相当于打开一个文件描述符.我想知道:1.如何设计一个高效的查看某个进程存活状态的算法,或者有没有一个系统调用来实现这种功能?
2.如果不能查看状态,能否在进程B异常退出时捕获一个系统信号,调用我自己的信号处理函数?
希望大家给予帮助!谢谢.
...全文
1644 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hu_zy 2006-12-08
  • 打赏
  • 举报
回复
关于readlink()的使用可以 man 2 readlink,就知道了。
hu_zy 2006-12-08
  • 打赏
  • 举报
回复
readlink(/proc/<pid>/cwd, buff, buffsize);

返回-1,or buff不是你进程B的名字,可以认为B已经不存在。
lurenfu 2006-12-07
  • 打赏
  • 举报
回复
如何利用/proc文件系统
cat /proc/b_pid/status
这里b_pid是你进程B的pid,看看输出结果,有一栏是State

你要利用/proc文件系统时,int fd = open( "/proc/pid/status", O_RDONLY );
这里pid是实际的进程的pid,如果open失败,刚进程显然不存在,然后读取该文件的内容,找出State
evawu999 2006-12-07
  • 打赏
  • 举报
回复
不错,让我懂了不少东西,发现了一些自己认识上的错误,现在写出来,大家帮忙看看我的自我否定是否正确,谢谢!

1。本来我想建议楼主用本地socket来进行通讯,读取数据前看socket里面是否有数据,如果没有则证明链接断开。但发现楼主是要进程间通信,所以不适用本地socket,对不?

2。我认为任何进程推出可能产生的信号都不相同,可能出现断开错误EINET,或者内存错误(抱歉我忘了宏名字了),但是hqx8211建议的是在A中调用kill来查看B的状态,这个很高明,佩服!

最后to hqx8211:
能不能帮忙解释一下如何利用/proc文件系统?谢了!
xdspower 2006-12-07
  • 打赏
  • 举报
回复
不知道上面的回答是否能解决楼主的问题,不过我又想到一个问题,就是不管怎么说,前面的方法都不是实时的方法!无论那种机制都有一定的处理时延,你如果作的实时系统,你要考虑到这样的问题,做好处理。
xdspower 2006-12-07
  • 打赏
  • 举报
回复
hqx8211()的回答很全面,根据楼主的意思,采用最后一种方法是最恰当的,但可以适当变换下,因为是A向B发包,则你可以在这个通讯中建立一个反馈机制,来表明B接收到信息,这同样就是对B运行状态的检测。
ocor 2006-12-07
  • 打赏
  • 举报
回复
Good answer!
hqx8211 2006-12-07
  • 打赏
  • 举报
回复
P O S I X . 1将信号编号0定义为空信号。如果s i g n o参数是0,则k i l l仍执行正常的错误检查,但不发送信号。这常被用来确定一个特定进程是否仍旧存在。如果向一个并不存在的进程发送空信号,则k i l l返回-1,e r r n o则被设置为E S R C H。但是,应当了解,U N I X系统在经过一定时间后会重新使用进程I D,所以一个现存的具有所给定进程I D的进程并不一定就是你所想要的进程。
-------上面转自APUE-------

在Linux下,还有一种方法检查某个进程是否存在:利用/proc文件系统. /proc/B_pid/stat里面有进程的状态,进程可执行文件名等.如果该文件不存在了,那肯定B退出了.如果存在,可以检查状态和文件名是否正确.效率可能比PS还是高一些,因为/proc是虚拟文件系统,存在与内存中.

还有就是自己定义心跳包了,B定期发送心跳包,如果隔一段时间没有收到心跳包,就认为B死了.
Cemondd 2006-12-07
  • 打赏
  • 举报
回复
麻烦hqx8211详细解释一下.谢谢~
hqx8211 2006-12-07
  • 打赏
  • 举报
回复
kill(B_pid, 0).
xdspower 2006-12-07
  • 打赏
  • 举报
回复
我觉得不存在什么老路新路问题,其实本机socket通讯来实现一些应用比系统内核对象通讯来实现应用可能对以后的系统分布(多机)架设更有利,这时你只需要把通讯的对方主机信息变更就可以了,可能程序都可以不重新编译。
由此可见很多方法之间不存在绝对的优劣差异,而仅仅是适应范围不同而已,或者是环境限制所致。
Cemondd 2006-12-07
  • 打赏
  • 举报
回复
To lurenfu,
你这个方法我考虑过,也是需要打开一个类似文件描述符的东西,只是在内存中不知道效率会有多大提升?
Cemondd 2006-12-07
  • 打赏
  • 举报
回复
谢谢各位啦,to xdspower,我以前是用socket通讯的,即hqx8211所说的最后一种方案,后来改为用系统内核对象通讯了,如果再起用一个心搏过程,则又回到以前的老路上了,目前想想还是用kill方便些,只是效率还是略低,不知道各位还有什么好的建议.
再次感谢hqx8211!

23,125

社区成员

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

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