我应该在 zeroMQ 程序初始化中添加睡眠以避免 heisenbugs 吗?
Posted
技术标签:
【中文标题】我应该在 zeroMQ 程序初始化中添加睡眠以避免 heisenbugs 吗?【英文标题】:Should I add sleeps to zeroMQ program initialization to avoid 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) ,这似乎使问题消失了。我对此不满意... 【参考方案1】:您必须假设在 PUB 上发送的消息在建立连接之前不会到达 SUB 套接字。建立连接需要一些有限的时间(如果非常短的话),因此在那个小窗口中发送的任何消息都不会到达尚未连接的 SUB。正如您所建议的,避免这种情况的一种简单方法是在绑定后向主服务器添加睡眠。这并不完全可靠,因为从技术上讲,worker 的连接速度可能非常慢,或者在 master 之后启动,并且当它们成功时没有实际的信号。
如果您确实需要确认工作人员已连接,一种更可靠的方法是使用握手机制,以便工作人员向主设备发送一个小的“嗨,我准备好了”消息(在不同的频道上)连接后。然后,master 仅在收到必要数量的握手后才开始发布消息(取决于您的应用程序的适当逻辑)。
【讨论】:
实际上,失败的是“嗨,我准备好了”握手。该过程是这样工作的:所有进程连接/绑定所有套接字;工人将“工人 x 准备好”发送给主人(重复);在 master 观察到所有准备好的信号后 master 发布“go!”。那时并不是所有的工人都看到了“走!”信号(如果我没记错的话)。 你能发布实际代码吗?如果你做得对,就可以编写可靠的代码而无需休眠。 我修好了。关键是要确保工人在他们准备好交给主人之前,能听到主人的出版物。我仍然使用短睡眠来防止握手阶段的忙循环。谢谢!以上是关于我应该在 zeroMQ 程序初始化中添加睡眠以避免 heisenbugs 吗?的主要内容,如果未能解决你的问题,请参考以下文章
我应该将啥传递给 SQLitePCL.raw.SetProvider() 以避免“'Microsoft.Data.Sqlite.SqliteConnection' 的类型初始化程序引发异常”