全局变量-如何在python的子进程中跳出循环



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

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

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

我的想法是这样的:

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

但是我需要设置breakout。

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

如果您真的想通过共享变量来实现这一点,请参阅文档中进程之间的共享状态,但简短的版本是:您创建一个multiprocessing.Value。然后您使用multiprocessing.Condition来保护该值不受竞争的影响,因为否则,就不能保证子进程会看到来自父进程的更改。

当然,您可以通过创建最小大小的mmap并仅使用m[0]作为标志和m.flush()而不是条件来实现这一点,但这并不真正简单。

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

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

而且,我突然想到,您也许可以用其他方法简化您的设计,从而完全消除这个问题。在读取和处理作业之间是否需要一个文件,而不是一个队列,或者甚至只是一个直接的顺序管道?你是否可以将用户输入和套接字放入同一个事件循环(如果用户输入是stdin,则普通的select,并且你不关心Windows;如果用户输入是Qt GUI,使用QSocket而不是socket.socket;twisted,如果你愿意学习twisted;等等)。或者,是否存在真正的用户输入,或者只是"立即退出"(或"立即关闭套接字并处理剩余的消息"),您可以使用^C处理这些输入?

考虑检查是否存在"毒丸"以跳出循环,而不是使用多处理变量。

例如:

data, addr = sock.recvfrom(packetSize)

转换成:

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

可以通过发送None值来通知进程跳出循环。我不确定你的sock是否可以发送/接收None,但一般的想法是一样的。

相关内容

  • 没有找到相关文章

最新更新