问题:Python中的多处理器同时触发其他代码(concurrent.forets.ProcessPoolExecuto



我写这段代码是为了学习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,它本身不导入。

相关内容

最新更新