如何在python中打破子进程中的循环

时间:2013-01-18 00:16:11

标签: python global-variables multiprocessing

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

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

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

我的想法是这样的:

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

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

2 个答案:

答案 0 :(得分:1)

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

如果您确实希望通过共享变量来执行此操作,请参阅文档中的Sharing state between processes,但简短版本为:您创建multiprocessing.Value。然后使用multiprocessing.Condition来保护该值不受种族影响,因为否则,无法保证子进程看不到父进程的更改。

当然你可以通过例如假冒创建最小尺寸mmap并仅使用m[0]作为标记和m.flush()而不是条件,但这并不是更简单。

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

在这种情况下可能还有另一个更简单的选项:首先不要使用multiprocessing。很明显,你的后台任务不受CPU约束,因为它只是从套接字读取循环,所以为什么不只是threading

此外,我可能会以其他方式简化您的设计,这可能会完全消除此问题。您是否需要读取和处理作业之间的文件,而不是队列,甚至只是直接顺序管道?如果用户输入为select并且您不关心Windows,可以将用户输入和套接字放入同一个事件循环(普通旧stdin;使用QSocket代替socket.socket如果用户输入是Qt GUI; twisted如果您愿意学习twisted;等等。或者,是否有真正的用户输入,或者只是“立即退出”(或“关闭套接字并立即处理剩余的消息”),您可以使用^ C处理它?<​​/ p>

答案 1 :(得分:0)

不要使用多处理变量,而应考虑检查是否存在“毒丸”以打破循环。

例如,更改:

data, addr = sock.recvfrom(packetSize)

类似于:

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

您可以通过向其发送None值来指示进程突破其循环。我不确定您的sock是否可以发送/接收None,但总的想法是一样的。