gpt4 book ai didi

Python multiprocessing.Process 调用自己加入

转载 作者:太空宇宙 更新时间:2023-11-04 02:31:38 24 4
gpt4 key购买 nike

我有这个代码:

class ExtendedProcess(multiprocessing.Process):
def __init__(self):
super(ExtendedProcess, self).__init__()
self.stop_request = multiprocessing.Event()

def join(self, timeout=None):
logging.debug("stop request received")
self.stop_request.set()
super(ExtendedProcess, self).join(timeout)

def run(self):
logging.debug("process has started")
while not self.stop_request.is_set():
print "doing something"
logging.debug("proc is stopping")

当我在进程上调用 start() 时,它应该永远运行,因为 self.stop_request() 没有设置。几毫秒后 join() 被自己调用并中断运行。到底是怎么回事!?为什么 join 会被自己调用?

此外,当我启动调试器并逐行运行时,它突然工作正常......我错过了什么?

好的,感谢 ely 的回答,原因让我印象深刻:

存在竞争条件 -

  1. 创建新流程...
  2. 当它自行启动并即将运行 logging.debug("process has started") 时,主函数结束。
  3. main 函数调用 sys exit 并在 sys exit 上调用 python 调用所有已完成的进程以使用 join() 关闭。
  4. 因为进程实际上并没有命中“while not self.stop_request.is_set()”,所以调用了 join 和“self.stop_request.set()”。现在 stop_request.is_set 并且代码关闭。

最佳答案

正如更新后的问题中提到的,这是因为竞争条件。下面我给出了一个初始示例,突出显示了一个简单的竞争条件,其中竞争针对整个程序退出,但这也可能是由其他类型的范围退出或涉及您的流程的其他一般竞争条件引起的。

我复制了您的类定义并添加了一些“主要”代码来运行它,这是我的完整 list :

import logging
import multiprocessing
import time


class ExtendedProcess(multiprocessing.Process):
def __init__(self):
super(ExtendedProcess, self).__init__()
self.stop_request = multiprocessing.Event()

def join(self, timeout=None):
logging.debug("stop request received")
self.stop_request.set()
super(ExtendedProcess, self).join(timeout)

def run(self):
logging.debug("process has started")
while not self.stop_request.is_set():
print("doing something")
time.sleep(1)
logging.debug("proc is stopping")


if __name__ == "__main__":
p = ExtendedProcess()
p.start()
while True:
pass

上面的代码 list 在我使用 Python 2.7.11 和 3.6.4 时按预期运行。它无限循环并且进程永远不会终止:

ely@eschaton:~/programming$ python extended_process.py 
doing something
doing something
doing something
doing something
doing something
... and so on

但是,如果我在主要部分中使用此代码,它会立即退出(如预期的那样):

if __name__ == "__main__":
p = ExtendedProcess()
p.start()

这会退出,因为解释器到达程序的末尾,这反过来会触发自动销毁 p 对象,因为它超出了整个程序的范围。

请注意,这也可以解释为什么它在调试器中对您有效。这是一个交互式编程 session ,因此在您启动 p 之后,调试器环境允许您等待并检查它……除非您以某种方式在某个范围内调用它,否则它不会自动销毁在单步执行调试器时退出。

只是为了验证加入行为,我也尝试了这个主 block :

if __name__ == "__main__":
log = logging.getLogger()
log.setLevel(logging.DEBUG)
p = ExtendedProcess()
p.start()
st_time = time.time()
while time.time() - st_time < 5:
pass
p.join()
print("Finished!")

它按预期工作:

ely@eschaton:~/programming$ python extended_process.py 
DEBUG:root:process has started
doing something
doing something
doing something
doing something
doing something
DEBUG:root:stop request received
DEBUG:root:proc is stopping
Finished!

关于Python multiprocessing.Process 调用自己加入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49050818/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com