我写这段代码是为了学习Python中的多处理。
import concurrent.futures
print("A")
tic = time.perf_counter()
def test():
k = 1
s = 0
print(f"Starting ... ")
for i in range(10000000):
if i % 2 == 0:
s += 4/k
else:
s -= 4/k
k += 2
print(f"... finished!")
def main():
with concurrent.futures.ProcessPoolExecutor() as executor:
executor.submit(test)
executor.submit(test)
if __name__ == '__main__':
main()
toc = time.perf_counter()
print(f"Took {toc - tic:0.4f} seconds")
我希望能有几秒钟的纯输出,但它也运行了三次打印("a"(:
A
A
Took 0.0000 seconds
Starting ...
A
Took 0.0000 seconds
Starting ...
... finished!
... finished!
Took 4.0650 seconds
我在谷歌上查找了各种例子,但似乎无法确定问题所在。有什么建议吗?
因为您将A
的打印和计时放在主函数的之外,所以在启动程序和启动executor.submit(test)
的每个进程时,这些命令都会运行一次。这是因为ProcessPoolExecutor创建了新实例,这些实例将自己导入到新进程中,从而执行每个实例的所有全局变量。
它也在文档中:
main模块必须可由辅助子流程导入。这意味着ProcessPoolExecutor将无法在交互式解释器中工作
文件:https://docs.python.org/3/library/concurrent.futures.html#processpoolexecutor
要解决这个问题,请将打印语句移动到主函数中,如下所示:
import concurrent.futures, time
def test():
k = 1
s = 0
print(f"Starting ... ")
for i in range(10000000):
if i % 2 == 0:
s += 4/k
else:
s -= 4/k
k += 2
print(f"... finished!")
def main():
pass
with concurrent.futures.ProcessPoolExecutor() as executor:
executor.submit(test)
executor.submit(test)
if __name__ == '__main__':
print("A")
tic = time.perf_counter()
main()
toc = time.perf_counter()
print(f"Took {toc - tic:0.4f} seconds")
结果:
A
Starting ...
Starting ...
... finished!
... finished!
Took 3.7274 seconds
您也可以切换到ThreadPoolExecutor,它本身不导入。