【问题标题】:Should I add sleeps to zeroMQ program initialization to avoid heisenbugs?我应该在 zeroMQ 程序初始化中添加睡眠以避免 heisenbugs 吗?
【发布时间】:2012-02-29 03:27:04
【问题描述】:

我正在做一个 zeroMQ 概念证明,它涉及一个主进程,该进程发布控制命令并从任意数量的工作进程推送和拉取数据。

似乎在初始化时,如果我使用 shell 脚本启动 master 和 worker(单独的进程)有时会不同步。但是,如果我以任何顺序手动启动它们(在单独的控制台窗口中),我从未见过这种情况。我开始考虑在每个进程绑定/连接到套接字之后添加一个 sleep() 以避免这种明显的 heisenbug - 但我也想知道我是否只是愚蠢。有什么建议吗?

下面是偶尔失败的 shell 脚本的样子。主人使用 PUB 和 PUSH 与工人交谈,并使用 PULL 套接字获取信息。我认为 heisenbug 是由于某个工人有时看不到来自 master 的 PUB 消息引起的。

echo "starting worker A in background"
python pWorkerA.py > /tmp/A.out &
echo "starting worker B in background"
python pWorkerB.py > /tmp/B.out &
echo "starting master"
python abMaster.py

如果我使用 sleep(),我觉得我在作弊

【问题讨论】:

  • 遗憾的是,我只是尝试在套接字初始化后在所有进程的顶部添加一个 sleep(0.1) ,这似乎使问题消失了。我对此不满意...

标签: zeromq


【解决方案1】:

您必须假设在 PUB 上发送的消息在建立连接之前不会到达 SUB 套接字。建立连接需要一些有限的时间(如果非常短的话),因此在那个小窗口中发送的任何消息都不会到达尚未连接的 SUB。正如您所建议的,避免这种情况的一种简单方法是在绑定后向主服务器添加睡眠。这并不完全可靠,因为从技术上讲,worker 的连接速度可能非常慢,或者在 master 之后启动,并且当它们成功时没有实际的信号。

如果您确实需要确认工作人员已连接,一种更可靠的方法是使用握手机制,以便工作人员向主设备发送一个小的“嗨,我准备好了”消息(在不同的频道上)连接后。然后,master 仅在收到必要数量的握手后才开始发布消息(取决于您的应用程序的适当逻辑)。

【讨论】:

  • 实际上,失败的是“嗨,我准备好了”握手。该过程是这样工作的:所有进程连接/绑定所有套接字;工人将“工人 x 准备好”发送给主人(重复);在 master 观察到所有准备好的信号后 master 发布“go!”。那时并不是所有的工人都看到了“走!”信号(如果我没记错的话)。
  • 你能发布实际代码吗?如果你做得对,就可以编写可靠的代码而无需休眠。
  • 我修好了。关键是要确保工人在他们准备好交给主人之前,能听到主人的出版物。我仍然使用短睡眠来防止握手阶段的忙循环。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 2015-09-26
  • 1970-01-01
  • 2012-10-14
  • 2021-03-27
  • 2014-09-11
  • 1970-01-01
相关资源
最近更新 更多