0

我觉得这应该是一个简单的解决方案,但这是一天结束的时候,我已经脑残了。我目前正在产生几个进程,一个进程正在接收数据并将其存储到文件中。另一个是解析数据,第三个是等待用户输入以知道何时停止存储数据。

我需要知道如何做的是突破我的 while 循环。我不想使用父进程设置的全局变量,但如果需要,我可以这样做。现在我的代码看起来像这样:

while(packetReceived < totalToReceive):
    data, addr = sock.recvfrom(packetSize)

我的想法是这样的:

breakout = 0
while(packetReceived < totalToReceive || breakout != 0):
    data, addr = sock.recvfrom(packetSize)

但后来我需要以某种方式设置突破。任何帮助将不胜感激。

4

2 回答 2

1

您不能仅通过在父进程中使用全局变量来共享状态。这可能看起来有效,但它只在某些时候有效;它既不可靠也不可预测。除了在 Windows 上,它可靠且可预测地永远不会工作;每个孩子都将永远拥有自己独立的旗帜副本,因此您永远不会退出。

如果您真的想通过共享变量来做到这一点,请参阅文档中的进程之间的共享状态,但简短的版本是:您创建一个multiprocessing.Value. 然后您使用 amultiprocessing.Condition来保护该值免受竞争,因为否则,无法保证子进程将永远看到父进程的更改。

当然,您可以通过例如创建一个mmap最小尺寸并仅将m[0]其用作标志而m.flush()不是条件来伪造它,但这实际上并不简单。

另一种方法是使用multiprocessing.Pipe或类似的方法传递“立即关闭”消息。子进程可以各自生成一个线程来阻塞管道,或者您可以将管道和您的套接字扔select在一起,或者所有其他常见的技巧。

在这种情况下,可能还有另一个更简单的选择:一开始就不要使用multiprocessing。显然,您的后台任务不受 CPU 限制,因为它只是循环从套接字读取,那么为什么不只是threading呢?

此外,让我感到震惊的是,您也许可以通过其他方式简化您的设计,这可以完全消除这个问题。您是否需要读取和处理作业之间的文件而不是队列,甚至只是一个直接顺序管道?您能否将用户输入和套接字扔到同一个事件循环中(select如果用户输入是stdin并且您不关心 Windows,则使用普通旧的;如果用户输入是 Qt GUI,则使用 aQSocket而不是 a ;如果您愿意学习; ETC。)。或者,是否有真正的用户输入,或者只是“立即退出”(或“关闭套接字并立即处理剩余的消息”),您可以使用 ^C 处理?socket.sockettwistedtwisted

于 2013-01-18T00:28:29.557 回答
0

与其使用多处理变量,不如考虑检查是否存在“毒丸”以跳出循环。

例如,更改:

data, addr = sock.recvfrom(packetSize)

类似于:

received = sock.recvfrom(packetSize)
if received is None:
    break
data, addr = received

None您可以通过向进程发送一个值来指示进程跳出其循环。我不确定您是否sock可以发送/接收None,但总体思路是一样的。

于 2013-01-18T00:35:45.247 回答