【问题标题】:How to make 2 applications run each other in linux?如何让 2 个应用程序在 linux 中相互运行?
【发布时间】:2013-05-23 10:43:45
【问题描述】:

情况如下:

我们有一个主应用程序和一个观察程序应用程序。 它们都是 c++ 应用程序。它们都使用 daemon(1,0) 函数。

Watcher 检查主应用程序是否正在运行,如果它发现主进程不存在(崩溃)或主进程没有响应(应用程序通过 TCP 相互“对话”,这就是它如何知道它是否挂起)然后它运行主或重新启动它。

现在,用户可以更改连接的 TCP 设置,并通过主应用程序完成。更改后,必须重新启动 watcher 以加载新配置。这是从主应用程序完成的。

事实上,它工作正常。
1. 在启动时主应用程序确实会杀死现有的观察者进程并再次运行它。 [这是正确的]
2. Watcher 应用程序确实会杀死 main 并再次运行它。 [这是正确的]

但是

  1. 如果我运行 Main,而后者又启动 Watcher,
  2. 然后杀死主,让守望者一个人呆着。
  3. Watcher 发现不再有 Main,因此它再次启动它。
  4. Main 再次启动,杀死 watcher 并尝试再次启动它....
  5. 在这一点上,发生了某种无意义的事情。它启动了观察者(我可以看到通过 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。

  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

  2. 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

  3. 现在,我通过 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

    注意到现在谁拥有监听套接字的变化了吗?这是怎么发生的?

  4. Watcher 发现 Main 已消失,因此它使用脚本文件启动它。

  5. 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


【解决方案1】:

如何使用自定义信号(甚至在另一个端口上监听管理命令)?使用 kill -9 就是在玩弄进程树,比如子进程获得了父资源(端口等)的控制权

那么,除此之外,当 Watcher 启动 Main 进程时,为什么它会假设正在运行的 Watcher 实例应该被杀死?一个原因是现在 Watcher 是 Main 的父级,所以我可以看到这会造成什么麻烦。

这归结为两个进程需要在“kill”信号之外进行通信。

使用信号量或其他操作系统级别的通信机制在两者之间进行协调。

【讨论】:

  • 嗨,这个想法是 watcher 会查看 Main,所以如果 main 崩溃或冻结,Watcher 会重新启动它。他们使用一个通用的配置文件,当配置改变时(使用 Main) - 需要重新加载观察者,这就是为什么 Main 想要杀死并重新启动观察者,所以它加载新的配置。我已经改变了 Watcher 的工作方式,如果它发现 Main 没有以应有的方式响应它,它会检查配置更改。以为让它互相残杀会更容易,但我错了。
  • 每个人都需要能够知道何时应该重新启动另一个,以避免这些类型的递归操作。也许 Main 有一个 Watcher 在重新启动 Main 时使用的参数,当 Main 启动时,它会检查该参数,如果为 true,则 Main 跳过重新启动 Watcher。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多