rfyiamcool2016年1月18日  0 Comments

遇到一个坑,Can’t pickle instancemethod …

前言:

今天写了一个小脚本,因为涉及到cpu运算的事件,所以用了多进程.  因为大量复用了以前的类,就遇到了奇怪的问题。 我这里就不暴露我的业务代码,临时写了个小demo供大家测试下。

文章写的不是很严谨,欢迎来喷,另外该文后续有更新的,请到原文地址查看更新。

http://xiaorui.cc/2016/01/18/python-multiprocessing%E9%81%87%E5%88%B0cant-pickle-instancemethod%E9%97%AE%E9%A2%98/

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#blog: xiaorui.cc

import time

import multiprocessing

class Go():

def run(self,args):

print 'end'

print args

pool = multiprocessing.Pool(processes=1)

pool.apply_async(Go().run,(60,))

pool.close()

pool.join()

然后你会遇到下面的报错信息: >

Exception in thread Thread-2:
Traceback (most recent call last):
  File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py”, line 810, in __bootstrap_inner
    self.run()
  File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py”, line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py”, line 342, in _handle_tasks
    put(task)
PicklingError: Can’t pickle <type ‘instancemethod’>: attribute lookup __builtin__.instancemethod failed

我们看下multiprocessing pool.py的源码,纠结下哪里出的问题.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#blog: xiaorui.cc

#入口函数.

def apply_async(self, func, args=(), kwds={}, callback=None):

assert self._state == RUN

result = ApplyResult(self._cache, callback)

self._taskqueue.put(([(result._job, None, func, args, kwds)], None))

return result

def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None):

put = outqueue.put  #put函数

@staticmethod

def _handle_tasks(taskqueue, put, outqueue, pool):

for taskseq, set_length in iter(taskqueue.get, None):

i = -1

for i, task in enumerate(taskseq):

if thread._state:

debug('task handler found thread._state != RUN')

break

try:

put(task)        #这里报错....

except IOError:

debug('could not put task on queue')

PicklingError: Can’t pickle <type ‘instancemethod’>: attribute lookup __builtin__.instancemethod failed 这个报错给出的信息很明显… 不知道这算是multiprocessing的坑,还是pickle的坑. 看了些stackoverflow回复,貌似在python3.4解决了这类问题.

我们首先要明白,这问题是怎么引起的?

python的multiprocessing pool进程池隐形的加入了一个任务队列,在你apply_async的时候,他会使用pickle序列化对象,但是python 2.x的pickle应该是不支持这种模式的序列化.

解决的方法有这么几种: >

第一种:

把执行的函数放在外面,这样就避免了把类的实例序列化.   如果不能直接放在外面的化,可以再用一个的函数来包装下.

第二种:

不使用进程池,而使用Process函数解决fork进程,这样也避免了pickle序列化对象.

1

2

3

4

5

6

#blog: xiaorui.cc

import multiprocessing

p = multiprocessing.Process(target=Go().run, args=(1, ))

p.start()

p.join()

第三种:

使用copy_reg将MethodType注册为可序列化的方法

1

2

3

4

5

6

7

8

9

10

11

12

#blog: xiaorui.cc

import copy_reg

import types

def _pickle_method(m):

if m.im_self is None:

return getattr, (m.im_class, m.im_func.func_name)

else:

return getattr, (m.im_self, m.im_func.func_name)

copy_reg.pickle(types.MethodType, _pickle_method)

第四种,加入一个中间函数,使用getattr自省黑魔法调用真正的函数.

1

2

3

4

#blog: xiaorui.cc

def proxy(instance, *args):

getattr(instance(),'run')('xiaorui.cc')

END…

python multiprocessing遇到Can’t pickle instancemethod问题相关推荐

  1. python multiprocessing模块

    python multiprocessing模块 原文地址 multiprocessing multiprocessing支持子进程.通信和共享数据.执行不同形式的同步,提供了Process.Queu ...

  2. python multiprocessing manager list error: [Errno 2] No such file or directory

    python multiprocessing manager list error: [Errno 2] No such file or directory for i in range(AMOUNT ...

  3. Python Multiprocessing with PyCUDA

    Python Multiprocessing with PyCUDA 参考:https://stackoverflow.com/questions/5904872/python-multiproces ...

  4. python multiprocessing — 基于进程的并行

    概述 multiprocessing 是一个用与 threading 模块相似API的支持产生进程的包. multiprocessing 包同时提供本地和远程并发,使用子进程代替线程,有效避免 Glo ...

  5. dill:解决python的“AttributeError: Can‘t pickle local object”及无法pickle lambda函数的问题

    dill:解决python的"AttributeError: Can't pickle local object"及无法pickle lambda函数的问题 参考文章: (1)di ...

  6. 【Python】dill:解决python的“AttributeError: Can‘t pickle local object”及无法pickle lambda函数的问题

    [Python]dill:解决python的"AttributeError: Can't pickle local object"及无法pickle lambda函数的问题 pyt ...

  7. Python标准库中的pickle模块

     pickle  -  Python对象序列化. pickle模块实现了用于序列化和反序列化Python对象结构的二进制协议."pickle"是将Python对象层次结构转换为 ...

  8. python多路分支_用于多个参数的python multiprocessing pool.map

    在python多处理库中,是否有pool.map的变体支持多个参数? text ="test" def harvester(text, case): X = case[0] tex ...

  9. Python基础23_os,sys,序列化,pickle,json

    一. os 模块 所有关于操作系统的内容都在os模块     os.makedirs("d:/1PY/新建文件夹/宝宝")      # 可生成多层递归目录     os.remo ...

最新文章

  1. [**经典**] 电脑故障检查不完全流程图
  2. java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究
  3. unlink(file_name)
  4. 数列分段(信息学奥赛一本通-T1428)
  5. 用MATLAB玩转机器人--第五章 机器人的数学建模
  6. 7种最有效的懒人减肥方法,收藏了!
  7. Jmeter之app性能测试(ios,android)
  8. OpenWrt加入iptables 支持过滤字符串
  9. 如何去除WINRAR的广告
  10. 03 高等数学专题——多元函数微积分
  11. SubsamplingScaleImageView + Glide显示网络超大图片
  12. 使用青龙面板BP京东豆
  13. 对于uniapp的项目,获取设备的一些设备id,首次登陆设备的首台绑定,以及对项目的版本号进行对比进行app升级
  14. Kubernetes Pod Evicted
  15. Vue中登录验证成功后保存token,并每次请求携带并验证token操作
  16. 闭关修炼(十)单例设计
  17. 计算机二级报名时间2020年12月江苏省,2020年12月计算机二级考试报名时间及考试安排...
  18. 纯国产的大佬周志华,如何扛起了智能学界的一面大旗
  19. 应届毕业生工作7个月小结
  20. jzoj 3947. 【省常中JSOI模拟】收历史作业 最长不下降子序列

热门文章

  1. Mysql的int和bigint字段类型,映射到Java的Integer和Long类型时,勾选UNSIGNED无符号会导致越界转换。
  2. 系统大小端的头文件定义
  3. python PyQt5初级教程hello world
  4. SQL Server 2019中的行模式内存授予反馈
  5. 使用SQL Server日志传送将SQL数据库移动到其他服务器
  6. python 自动化测试
  7. 获取移除指定Url参数(原创)
  8. POJ 1759 Garland
  9. 树的基本定义表示方法
  10. Windows as a Service(4)——使用Intune管理Windows10更新