下面的代码示例在两台Linux机器上按我的想法运行:在运行Red Hat 4.8.5-39内核的大型CentOS服务器上使用Python 3.6.8,在运行Debian 8.3.0-6内核的基于MX的机器上使用Python 3.7.3)
$ python3 testshared.py filename.dat
filename.dat
270623586670000.0
但是,在运行Mojave10.14.6的Mac上,使用Python 3.8.3,我得到一个错误,因为函数processBigFatRow()
中有foo=[]
。请注意,foo
是在启动进程池之前在getBigFatData()
中分配的。就像在Linux中一样,在getBigFatData()
中分配的foo
的版本被传递给进程,而在Mac上,进程只使用代码顶部的初始化(我必须将其放在那里,以便它们是global
变量)
我知道流程是主流程的“独立副本”,您不能在一个流程中分配全局变量,而期望它们在另一个流程中发生变化。但是,对于在并行进程启动之前已经设置好的、仅用于引用的变量,该怎么办呢?就好像整个OSs的过程拷贝是不一样的。哪一个“按设计”工作
代码示例:
import pylab as pl
from concurrent import futures
import sys
foo = []
bar = []
def getBigFatData(filename):
global foo, bar
# get the big fat data
print(filename)
foo = pl.arange(1000000).reshape(1000,1000)
# compute something as a result
bar = pl.sum(foo, axis=1)
def processBigFatRow(row):
total = pl.sum(foo[row,:]**2) if row % 5 else bar[row]
return total
def main():
getBigFatData(sys.argv[1])
grandTotal = 0.
rows = pl.arange(100)
with futures.ProcessPoolExecutor() as pool:
for tot in pool.map(processBigFatRow, rows):
grandTotal+=tot
print(grandTotal)
if __name__ == '__main__':
main()
编辑:
正如所建议的那样,我在MX Linux机器上测试了Python 3.8.6,它可以正常工作
因此,它可以在Linux上使用Python 3.6.8、3.7.3和3.8.6。 但在Mac上使用Python3.8.3时,它不起作用
编辑2:
On Unix a child process can make use of a shared resource created in a parent process using a global resource.
所以它在Windows上不起作用(这不是最佳实践),但它在Mac上不起作用吗
这是因为,在MacOS上,Python3.8中的default multiprocessing start method has changed。它从
fork
(py37)到spawn
(py38),导致相当一部分咬牙与
spawn
:全局变量不与多进程进程共享因此,实际上,作为一个快速修复方法,使用^{} 在所有^{} 调用中指定一个
'fork'
上下文。但是要注意上面的警告;一个长期的解决办法是使用多处理docs上列出的技术之一共享变量例如,在上面的代码中,替换:
与:
备选方案:
当您正在编写一两个小脚本,并且确信没有人在某处使用不同的} 在
main
调用您的代码时,您可以使用^{main
代码块中一次性设置默认的启动方法:但一般来说,我更喜欢第一种方法,因为您不必假设调用方事先设置了start方法。根据文件:
您正在比较两个不同python版本中相同代码的输出。内置模块可能是相同的,也可能在3.6和3.8之间发生了重大变化。在继续之前,您应该在两个地方的相同python版本上运行代码
相关问题 更多 >
编程相关推荐