我觉得这应该是一个简单的解决方案,但这是一天的结束,我脑子里死了。 我目前正在产生几个进程,一个进程正在接收数据并将数据存储到文件中。另一个是解析数据,第三个是等待用户输入知道何时停止存储数据。
我需要知道怎么做才能突破我的while循环。我不想使用父进程设置的全局变量,但如果需要,我可以这样做。 现在我的代码看起来像这样:
while(packetReceived < totalToReceive):
data, addr = sock.recvfrom(packetSize)
我的想法是这样的:
breakout = 0
while(packetReceived < totalToReceive || breakout != 0):
data, addr = sock.recvfrom(packetSize)
然后我需要以某种方式设置突破。任何帮助将不胜感激。
答案 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
,但总的想法是一样的。