【发布时间】:2013-05-23 10:43:45
【问题描述】:
情况如下:
我们有一个主应用程序和一个观察程序应用程序。 它们都是 c++ 应用程序。它们都使用 daemon(1,0) 函数。
Watcher 检查主应用程序是否正在运行,如果它发现主进程不存在(崩溃)或主进程没有响应(应用程序通过 TCP 相互“对话”,这就是它如何知道它是否挂起)然后它运行主或重新启动它。
现在,用户可以更改连接的 TCP 设置,并通过主应用程序完成。更改后,必须重新启动 watcher 以加载新配置。这是从主应用程序完成的。
事实上,它工作正常。
1. 在启动时主应用程序确实会杀死现有的观察者进程并再次运行它。 [这是正确的]
2. Watcher 应用程序确实会杀死 main 并再次运行它。 [这是正确的]
但是
- 如果我运行 Main,而后者又启动 Watcher,
- 然后杀死主,让守望者一个人呆着。
- Watcher 发现不再有 Main,因此它再次启动它。
- Main 再次启动,杀死 watcher 并尝试再次启动它....
- 在这一点上,发生了某种无意义的事情。它启动了观察者(我可以看到通过 netstat 命令获取的 TCP 端口),但没有名为观察者的进程。
如果正常 netstat 显示tcp 0 0 IP:TCP_PORT LISTEN Watcher,现在它显示tcp 0 0 IP:TCP_PORT LISTEN Main。
就好像观察者在那里,但在主进程中。
我使用脚本来运行应用程序。 观察者使用这个
#!/bin/sh
killall -9 Main
./Main
像system("./runMain.sh&");一样运行它
主要使用这个
#!/bin/sh
killall -9 Watcher
./Watcher
像system("./runWatcher.sh&");一样运行它
我做错了什么?我如何运行它们,以便它们可以在需要时相互重新启动并始终在单独的进程中启动?
到目前为止,我还尝试使用nohup 运行脚本,结果是一样的。
编辑 1:
注意:这里的数字只是为了清楚起见。实际上PID当然不是1。
-
我运行 Main。 netstat 给我看:
tcp 0 0 192.168.0.1:7000 LISTEN (PID 1)Main
tcp 0 0 192.168.0.1:7001 LISTEN (PID 1)Main -
Main 使用脚本启动 Watcher。现在 netstat 向我展示了:
tcp 0 0 192.168.0.1:7000 LISTEN (PID 1)Main
tcp 0 0 192.168.0.1:7001 LISTEN (PID 1)Main
tcp 0 0 192.168.0.1:8000 LISTEN (PID 2)Watcher -
现在,我通过
killall -9 Main手动杀死 Main。现在 netstat 向我展示了:tcp 0 0 192.168.0.1:7000 LISTEN (PID 2)Watcher
tcp 0 0 192.168.0.1:7001 LISTEN (PID 2)Watcher
tcp 0 0 192.168.0.1:8000 LISTEN (PID 2)Watcher注意到现在谁拥有监听套接字的变化了吗?这是怎么发生的?
Watcher 发现 Main 已消失,因此它使用脚本文件启动它。
-
Main 在启动时杀死 Watcher。 Netstat 显示:
tcp 0 0 192.168.0.1:7000 LISTEN (PID 3)Main
tcp 0 0 192.168.0.1:7001 LISTEN (PID 3)Main
tcp 0 0 192.168.0.1:8000 LISTEN (PID 3)Main
就是这样。 Watcher 再也不会运行了。
我尝试在 Eclipse 中调试,Watcher 崩溃而没有在daemon(1,0) 上抛出任何东西。
【问题讨论】:
-
你怎么知道 Watcher 没有启动但由于错误而终止?使用一些日志记录到文件来检测您的守护程序可能会有所帮助。
-
好吧,因为 Watcher 是唯一使用 TCP_PORT 的应用程序。假设它是 8000。Main 从不听 8000,只有 Watcher 听。然而,在最后一种情况下,它显示 main 监听 8000。
-
你说
It is as if watcher is there, but inside the Main process.但你肯定已经知道这不太可能(并且考虑到你是如何开始的...... system() 启动一个shell,然后启动一个新的shell您的脚本,然后执行它所做的任何事情),您需要挑战您确定的其他事情,而不是假设一切都是应该的(因为显然不是),找到这些事情的积极证据.. . 比如 Watcher 启动而不是停止。 -
查看我的编辑 1. 它很难调试,因为它不会抛出异常,什么都没有。它只是终止应用程序。我可以将断点放在
daemon()行上。再走 1 步,它就会崩溃。
标签: c++ linux shell process nohup