免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6048 | 回复: 8
打印 上一主题 下一主题

multiprocessing 在class中使用报错 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-27 16:29 |只看该作者 |倒序浏览
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
2 [报告]
发表于 2012-12-27 20:38 来自手机 |只看该作者
因为进程是借助于pickle传递参数的我。如果不能pickle。则会出错了。有很多的东西是无法pickle的。

论坛徽章:
0
3 [报告]
发表于 2013-11-13 16:18 |只看该作者
谢谢,是你说的那样。那现在有什么方法可以解决吗?总不能就这样就算了

论坛徽章:
0
4 [报告]
发表于 2013-11-13 16:31 |只看该作者
回复 3# HengGeneral

所以我的解决方案是, map的函数不用成员函数,在外部定义,或在go函数内部定义也可,没有self就方便了。暂时没有别的办法了,请高手拍砖。
这是网上的一个帖子,没看懂,请看懂的人指教:http://stackoverflow.com/questio ... iprocessing-pool-ma
   

论坛徽章:
0
5 [报告]
发表于 2013-11-13 16:33 |只看该作者
话说哪里有pickle?

论坛徽章:
4
白羊座
日期:2013-11-05 10:26:09冥斗士
日期:2015-11-17 14:19:55白银圣斗士
日期:2015-11-17 15:13:0815-16赛季CBA联赛之新疆
日期:2016-04-01 09:10:58
6 [报告]
发表于 2013-11-14 10:27 |只看该作者
回复 4# Hadron74


    刚开始用python不久,只能边看边试,在您说的那个贴子里,有三种方法,但是各自情况不一。
1. 使用copy_reg来注册需要pickle支持的方法。这种方法有个副作用(是帖子的后面的人说的),说是当注册的方法被调用完之后,在所在的processor上,会默认调用类对象的destructor方法,于是,当每个processor上,方法需要执行超过一次时,会出现找不到对象的问题。
2. 使用__call__,简单说:给类加一个def __call__()方法,在些方法中,调用需要传递的函数调用。这种方法不需要注册,可以使用,但是它也有使用限制,就是只能传递一个方法,当超过一个方法时,这种方法就不能解决问题了。
3. 使用metaclass相关的getattr方法,但是因为没有接触过多少python中multiprocessor的东西,看起来有些晕,那个人说,这种方法可以支持多个方法通过类传递,同时又不会出现方法2和1的问题。只是,我现在读的不是很明白--之后慢慢读,先把那人的代码再贴到这里一边吧。
  1. import multiprocessing
  2. import os

  3. def call_it(instance, name, args=(), kwargs=None):
  4.     "indirect caller for instance methods and multiprocessing"
  5.     if kwargs is None:
  6.         kwargs = {}
  7.     return getattr(instance, name)(*args, **kwargs)

  8. class Klass(object):
  9.     def __init__(self, nobj, workers=multiprocessing.cpu_count()):
  10.         print "Constructor (in pid=%d)..." % os.getpid()
  11.         self.count = 1
  12.         pool = multiprocessing.Pool(processes = workers)
  13.         async_results = [pool.apply_async(call_it,
  14.             args = (self, 'process_obj', (i,))) for i in range(nobj)]
  15.         pool.close()
  16.         map(multiprocessing.pool.ApplyResult.wait, async_results)
  17.         lst_results = [r.get() for r in async_results]
  18.         print lst_results

  19.     def __del__(self):
  20.         self.count -= 1
  21.         print "... Destructor (in pid=%d) count=%d" % (os.getpid(), self.count)

  22.     def process_obj(self, index):
  23.         print "object %d" % index
  24.         return "results"

  25. Klass(nobj=8, workers=3)
复制代码
基本上就是这些了,呵呵。

论坛徽章:
0
7 [报告]
发表于 2013-11-14 10:41 |只看该作者
可以看看我在这个帖子里写的

论坛徽章:
4
白羊座
日期:2013-11-05 10:26:09冥斗士
日期:2015-11-17 14:19:55白银圣斗士
日期:2015-11-17 15:13:0815-16赛季CBA联赛之新疆
日期:2016-04-01 09:10:58
8 [报告]
发表于 2013-11-14 10:49 |只看该作者
回复 7# laike9m


    刚刚大概看了下,中午有时间去看下两个库有什么区别,但是在3.3.2的说明页面上,有下面这个行:
PEP 3155, qualified name for classes and functions
想来应当是已经提前完成修补了吧。

论坛徽章:
0
9 [报告]
发表于 2013-11-14 19:23 |只看该作者
回复 8# icymirror


    3155是实现
  1. __qualname__
复制代码
属性,但是pickle的功能应该还是3154,3.3.2 release的页面里没看到3154。而3154是基于3155,所以也不可能是之前提供的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP