Joh*_*nck 4 python doctest concurrent.futures python-multiprocessing process-pool
此代码在常规 CPython 3.5 下运行良好:
import concurrent.futures
def job(text):
print(text)
with concurrent.futures.ProcessPoolExecutor(1) as pool:
pool.submit(job, "hello")
Run Code Online (Sandbox Code Playgroud)
但是如果你把它作为 运行python -m doctest myfile.py,它就会挂起。更改submit(job为submit(print使其不会挂起,使用ThreadPoolExecutor代替ProcessPoolExecutor.
为什么在 doctest 下运行时会挂起?
问题是,导入模块获取的锁(锁这取决于你的Python版本),看到的文档imp.lock_held。
锁在多处理上共享,因此您的死锁发生是因为您的主进程在导入您的模块时加载并等待子进程尝试导入您的模块,但无法获取锁以导入它,因为它当前正在导入通过您的主要流程。
阶梯形式:
myfile.pymyfile.py (它必须导入,myfile.py因为那是您job()定义函数的地方,这就是它没有死锁的原因print())。myfile.py=> 死锁。
所以我认为问题出在你的with陈述上。当你有以下
with concurrent.futures.ProcessPoolExecutor(1) as pool:
pool.submit(job, "hello")
Run Code Online (Sandbox Code Playgroud)
它强制执行线程并关闭它本身。当您将此作为主进程运行时,它会工作并为线程提供时间来执行作业。但是当你import把它作为一个模块时,它不会给后台线程一个机会,shutdown池上等待工作被执行,因此deadlock
因此,您可以使用的解决方法如下
import concurrent.futures
def job(text):
print(text)
pool = concurrent.futures.ProcessPoolExecutor(1)
pool.submit(job, "hello")
if __name__ == "__main__":
pool.shutdown(True)
Run Code Online (Sandbox Code Playgroud)
如果您愿意,这将阻止deadlock并且可以让您doctest像import模块一样运行
| 归档时间: |
|
| 查看次数: |
2792 次 |
| 最近记录: |