(Python 3.7)
我正在sentinel调用中使用multiprocessing.Process对象中的select()值,以避免调用join(),因为我还有其他文件描述符要等待。 / p>
根据文档,流程结束时,前哨“ 将变为”就绪”。”
当select()
调用返回前哨时,我假设:
is_alive()
是False
(文档:“ 大致上,从start()方法返回到子进程终止之间的某个过程对象都处于活动状态。”)< / li>
exitcode
不是None
(文档:“ 如果进程尚未终止,则为None。”)问题:
有时,select()
调用将返回哨兵,但是exitcode
和is_alive()
的值是错误的,好像该过程尚未真正结束。
当我使用forkserver
启动方法时,不会发生这种情况。
我当然可以更改start方法,或调用join()
以确保进程确实终止,但是我真的很想了解为什么会这样。
最小工作示例:(Try it online)
import multiprocessing
import select
import time
if __name__ == "__main__":
# If I uncomment this, the issue seems to disappear
# multiprocessing.set_start_method("forkserver")
iteration = 0
while True:
process = multiprocessing.Process(
target=time.sleep,
args=(.01,)
)
process.start()
select.select((process.sentinel,), (), ())
# The select() call has returned, the process should have ended
assert not process.is_alive(), f"try {iteration}: process is alive"
# same thing
# assert process.exitcode is not None
iteration += 1
process.close()
看似不一致的行为从何而来?我使用的模块错了吗?