multiprocessing.Pool报pickling error

现象

multiprocessing.Pool传递一个普通方法(不在class中定义的)时, 能正常工作.

from multiprocessing import Pool

p = Pool(3)
def f(x):
return x*x p.map(f, [1,2,3])

但在class中定义的方法使用multiprocessing.Pool会报pickling error错误.

报错代码

# coding: utf8
import multiprocessing class MyTask(object):
def task(self, x):
return x*x def run(self):
pool = multiprocessing.Pool(processes=3) a = [1, 2, 3]
pool.map(self.task, a) if __name__ == '__main__':
t = MyTask()
t.run()

会出现如下异常:

cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

原因:
stackoverflow上的解释:
Pool methods all use a queue.Queue to pass tasks to the worker processes. Everything that goes through the queue.Queue must be pickable. So, multiprocessing can only transfer Python objects to worker processes which can be pickled. Functions are only picklable if they are defined at the top-level of a module, bound methods are not picklable.

pool方法都使用了queue.Queue将task传递给工作进程。multiprocessing必须将数据序列化以在进程间传递。方法只有在模块的顶层时才能被序列化,跟类绑定的方法不能被序列化,就会出现上面的异常。

解决方法:

  1. 用线程替换进程
  2. 可以使用copy_reg来规避上面的异常.
  3. dill 或pathos.multiprocesssing :use pathos.multiprocesssing, instead of multiprocessing. pathos.multiprocessing is a fork of multiprocessing that uses dill. dill can serialize almost anything in python, so you are able to send a lot more around in parallel.

正确代码1

 # coding: utf8
from multiprocessing.pool import ThreadPool as Pool class MyTask(object):
def task(self, x):
return x*x def run(self):
pool = Pool(3) a = [1, 2, 3]
ret = pool.map(self.task, a)
print ret if __name__ == '__main__':
t = MyTask()
t.run()

正确代码2:

# coding: utf8
import multiprocessing
import types
import copy_reg 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) class MyTask(object):
def __init__(self):
self.__result = [] def task(self, x):
return x * x def result_collector(self, result):
self.__result.append(result) def run(self):
pool = multiprocessing.Pool(processes=3) a = [1, 2, 3]
ret = pool.map(self.task, a)
print ret if __name__ == '__main__':
t = MyTask()
t.run()

python 2.7 类中使用多进程(multiprocessing)执行类函数时的问题

python 2.7 类中使用多进程(multiprocessing)执行类函数时报错

PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

首先这是python2.7的一个bug,所以最简单的办法就是升级到python3

相关大神的文章的链接如下:

https://stackoverflow.com/questions/1816958/cant-pickle-type-instancemethod-when-using-multiprocessing-pool-map

http://bbs.chinaunix.net/thread-4111379-1-1.html

如果不升级python的话,就来改代码吧,我得改法如下:

import time
from multiprocessing import Pool
Class testClass():
def upMethod(self):
print '我是UP'
time.sleep(1)
def downMethod(self):
print '我是DOWN'
time.sleep(1)
def multiProcess(self):
p = Pool(2)
aObj=p.apply_async(self, args=('up',))#这里是重点
aObj=p.apply_async(self, args=('down',))#这里是重点
p.close()
p.join()
def __call__(self,sign):#这里是重点
if sign=='up':
return self.upMethod()
elif sign=='down':
return self.downMethod()
if __name__=='__main__':
testObj=testClass()
testObj.multiProcess()

关于__call__的说明 http://www.cnblogs.com/superxuezhazha/p/5793536.html

关于为什么这样改,大家看文章吧,我就不多BB了,有问题可以问我,大家一起探讨

multiprocessing.Pool报pickling error的更多相关文章

  1. python multiprocess pool模块报错pickling error

    问题 之前在调用class内的函数用multiprocessing模块的pool函数进行多线程处理的时候报了以下下错误信息: PicklingError: Can't pickle <type ...

  2. mysql报错"ERROR 1206 (HY000): The total number of locks exceeds the lock table size"的解决方法

    1. 问题背景         InnoDB是新版MySQL(v5.5及以后)默认的存储引擎,之前版本的默认引擎为MyISAM,因此,低于5.5版本的mysql配置文件.my.cnf中,关于InnoD ...

  3. 【MySQL笔记】mysql报错"ERROR 1206 (HY000): The total number of locks exceeds the lock table size"的解决方法

    step1:查看 1.1 Mysql命令行里输入"show engines:"查看innoddb数据引擎状态, 1.2 show variables "%_buffer% ...

  4. Appium - multiprocessing.pool.MaybeEncodingError-【 “Can’t pickle local object ‘PoolManager.__init__.<locals>.<lambda>‘】

    公司同事学习自动化新装环境后,run多进程测试用例时出错: multiprocessing.pool.MaybeEncodingError: Error sending result: ’<ap ...

  5. linux使用wkhtmltopdf报错error while loading shared libraries:

    官网提示 linux需要这些动态库.depends on: zlib, fontconfig, freetype, X11 libs (libX11, libXext, libXrender) 在li ...

  6. 发布报错:Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store

    发布报错:Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store 昨晚上传项目到AppStore,报了这个错,纳尼! ...

  7. python进程池:multiprocessing.pool

    本文转至http://www.cnblogs.com/kaituorensheng/p/4465768.html,在其基础上进行了一些小小改动. 在利用Python进行系统管理的时候,特别是同时操作多 ...

  8. javaMail使用163邮箱报535 Error: authentication failed

    javaMail使用网易163邮箱或者是126或者是网易其他邮箱报535 Error: authentication failed javax.mail.AuthenticationFailedExc ...

  9. 升级到macOS 10.12 mysqlb报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

    系统升级到macOS 10.12后启动mysql后,在终端输入mysql 报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' ...

随机推荐

  1. linux 、 CentOs ---> 环境变量设置

    Linux下环境变量设置 1.在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似的错 ...

  2. Paper Reading:个性化推荐系统的研究进展

    论文:个性化推荐系统的研究进展 发表时间:2009 发表作者:刘建国,周涛,汪秉宏 论文链接:论文链接 本文发表在2009,对经典个性化推荐算法做了基本的介绍,是非常好的一篇中文推荐系统方面的文章. ...

  3. zencart随机获取一张产品图片及价格小程序

    <?php //header("content-Type: text/html; charset=utf-8"); //@set_time_limit(1800); //@i ...

  4. 数组的新方法 forEach some filter findIndex

    forEach  some  filter  findIndex这些都属于数组的新方法,都会对数组中的每一项,进行遍历,执行相关的操作: 只不过在循环的时候有些不一样 参考资料:https://wan ...

  5. Nginx中ngx_http_proxy_module模块

    该模块允许将请求传递给另⼀一台服务器器指令:1 ,proxy_pass设置代理理服务器器的协议和地址以及应映射位置的可选 URI .作为协议,可以指定“ http 或 https .可以将地址指定为域 ...

  6. python_网络编程struct模块解决黏包问题

    为什么会出现黏包现象: 首先只有在TCP协议中才会出现黏包现象,是因为TCP协议是面向流的协议,在发送的数据传输的过程中还有缓存机制来避免数据丢失,因此,在连续发送小数据的时候,以及接收大小不符的时候 ...

  7. BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)

    题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...

  8. .Net Core: 跨域Cros概要

    读取配置 public class AppConfig { public static IConfigurationRoot Configuration { get; set; } public st ...

  9. LOJ #121. 「离线可过」动态图连通性 LCT维护最大生成树

    这个还是比较好理解的. 你考虑如果所有边构成一棵树的话直接用 LCT 模拟一波操作就行. 但是可能会出现环,于是我们就将插入/删除操作按照时间排序,然后依次进行. 那么,我们就要对我们维护的生成树改变 ...

  10. Gradle 如何打包 Spring Boot 可执行 JAR

    如何在 Gradle 中配置一个项目可以打包为 Spring Boot 可执行 Jar? 你首先需要添加到 org.springframework.boot 到插件中: 例如下面的代码: plugin ...