【问题标题】:Pickle error on code for converting numpy array into shared memory array将 numpy 数组转换为共享内存数组的代码出现 Pickle 错误
【发布时间】:2013-04-30 15:17:38
【问题描述】:

尝试使用此处的代码https://stackoverflow.com/a/15390953/378594 将 numpy 数组转换为共享内存数组并返回。运行以下代码:

shared_array = shmarray.ndarray_to_shm(my_numpy_array)

然后将 shared_array 作为参数传递到多处理池的参数列表中:

pool.map(my_function, list_of_args_arrays)

list_of_args_arrays 包含我的共享数组和其他参数。

导致如下错误

PicklingError: Can't pickle <class 'multiprocessing.sharedctypes.c_double_Array_<array size>'>: attribute lookup multiprocessing.sharedctypes.c_double_Array_<array size> failed

<array_size> 是我的 numpy 数组的线性大小。

我猜 numpy ctypes 或类似的东西发生了变化?

更多详情:

我只需要访问共享信息。进程不会进行任何编辑。

调用池的函数位于一个类中。类被初始化,函数被main.py文件调用。

【问题讨论】:

    标签: python numpy multiprocessing pickle


    【解决方案1】:

    显然,当使用multiprocessing.Pool 时,所有参数都被腌制了,因此使用multiprocessing.Array 没有用处。更改代码以便它使用一系列进程就可以了。

    【讨论】:

      【解决方案2】:

      我认为你把事情复杂化了: 不需要腌制数组(特别是如果它们是只读的):

      你只需要通过一些全局变量来保持它们可以访问:

      (已知在linux下工作,但在windows下可能不工作,不知道)

      import numpy as np,multiprocessing as mp
      class si:
        arrs=None
      
      def summer(i):
          return si.arrs[i].sum()
      
      def main():
          si.arrs=[np.zeros(100) for _ in range(1000)]
          pool = mp.Pool(16)
          res=pool.map(summer,range(1000))
          print res
      
      if __name__ == '__main__':
          main()
      

      如果你的数组需要读写,你需要使用这个: Is shared readonly data copied to different processes for Python multiprocessing?

      【讨论】:

      • 这看起来不错。如果文件被导入并且没有if __name__ == '__main':main(),您能否添加它的外观。这里的重要元素是什么,全局变量和函数summer 在同一个范围内?或者可能是池的定义和全局变量?
      • 重要的是在 mp.Pool() 之前初始化一个全局资源。例如。 main() 和 '_ main _' 可能在其他文件中(比如 sumfile.py) 只是在 main() 而不是 si.arr 中,它将是 sumfile.si.arr=[] 而不是pool.map(summer..) 将是 pool.map(sumfile.summer,...)
      • 奇怪,我正在更新存储在类中的全局变量,并且此更新是在调用 Pool() 之前完成的,但生成的进程仍然表现得好像我根本没有更改全局变量 -他们看到默认值(即None),尽管该值在主程序进程中确实发生了变化......
      • 也可以在这里查看docs.python.org/2/library/multiprocessing.html#windows。这似乎与您的示例相矛盾
      • 我猜如果您使用的 Windows 可能无法正常工作(它们的进程生成不同),但我从来没有尝试过 Windows。
      猜你喜欢
      • 2014-08-12
      • 2014-07-15
      • 2020-12-10
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 2014-01-25
      相关资源
      最近更新 更多