在Python> 3上使用带有部分和映射的多重处理的脚本,在2.7上可以正常工作,不能使'_thread.lock'腌制

问题描述

直到今天,我在Python 2.7上都使用以下代码将许多PNG图片matplotlib并行创建。今天,我尝试在Python 3.8上移动所有内容,而我无法适应的部分涉及使用multiprocessing完成的并行化。

这个想法是,我有一个脚本,该脚本需要从数据文件的不同时间步生成具有相似设置的多个图像。由于可以对绘图例程进行参数设置,因此我将在10个时间步的块上执行该例程,以分配给不同任务,以加快处理速度。

这是脚本的相关部分,鉴于其长度,我将不粘贴。

from multiprocessing import Pool
from functools import partial

def main():
    # arguments to be passed to the plotting functions
    # contain data and @R_910_4045@ion about the plot
    args = dict(m=m,x=x,y=y,ax=ax,winds_10m=winds_10m,mslp=mslp,....)

    # chunks of timesteps 
    dates = chunks(time,10)
    # partial version of the function plot_files(),see underneath 
    plot_files_param = partial(plot_files,**args)
    p = Pool(8)
    p.map(plot_files_param,dates)

def plot_files(dates,**args):
    first = True
    for date in dates:
        #loop over dates,retrieve data from args,e.g. args['mslp'] and do the plotting 

if __name__ == "__main__":
    import time
    start_time = time.time()
    main()
    elapsed_time=time.time()-start_time
    print_message("script took " + time.strftime("%H:%M:%s",time.gmtime(elapsed_time)))
        

这曾经在Python 2.7上可以正常工作,但是现在我收到了这个错误

Traceback (most recent call last):
  File "plot_winds10m.py",line 135,in <module>
    main()
  File "plot_winds10m.py",line 79,in main
    p.map(plot_files_param,dates)
  File "lib/python3.8/multiprocessing/pool.py",line 364,in map
    return self._map_async(func,iterable,mapstar,chunksize).get()
  File "lib/python3.8/multiprocessing/pool.py",line 771,in get
    raise self._value
  File "lib/python3.8/multiprocessing/pool.py",line 537,in _handle_tasks
    put(task)
  File "lib/python3.8/multiprocessing/connection.py",line 206,in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "lib/python3.8/multiprocessing/reduction.py",line 51,in dumps
    cls(buf,protocol).dump(obj)
TypeError: cannot pickle '_thread.lock' object

除了Python版本和软件包版本以外,唯一更改的是系统。我正在MacOS而不是Linux上进行测试,但这不会有太大的不同,尤其是因为它们都在conda环境中运行。

有人知道如何解决此问题吗?

(这是github存储库https://github.com/guidocioni/icon_forecasts/blob/master/plotting/plot_winds10m.py链接

解决方法

我想出了一个问题,以防万一有人拼命地来到这里寻求答案。

问题是我使用metpy.unit_array进行的某些转换会生成pint数组,由于某种原因,该数组不是pickable。然后,当我在args函数的partial中传递此数组时,出现了错误。

尝试使用.convert_units()进行转换或仅从数据中提取数组部分(使用.values.magnitude)确保我只传递了{{1} }数组或numpy且这些对象是可选取的。