Python multiprocessing.Pool-PicklingError:Can';t pickle<;类型';螺纹锁紧'>;:属性查找thread.lock失败

Python multiprocessing.Pool-PicklingError:Can';t pickle<;类型';螺纹锁紧'>;:属性查找thread.lock失败,python,threadpool,multiprocessing,pickle,Python,Threadpool,Multiprocessing,Pickle,多处理.Pool快把我逼疯了… 我想升级许多软件包,对于每一个软件包,我都必须检查是否有更高的版本。这是通过check\u one功能完成的。 主代码在Updater.update方法中:在那里我创建了Pool对象并调用map()方法 代码如下: def check_one(args): res, total, package, version = args i = res.qsize() logger.info('\r[{0:.1%} - {1}, {2} / {3}]

多处理.Pool
快把我逼疯了…
我想升级许多软件包,对于每一个软件包,我都必须检查是否有更高的版本。这是通过
check\u one
功能完成的。
主代码在
Updater.update
方法中:在那里我创建了Pool对象并调用
map()
方法

代码如下:

def check_one(args):
    res, total, package, version = args
    i = res.qsize()
    logger.info('\r[{0:.1%} - {1}, {2} / {3}]',
        i / float(total), package, i, total, addn=False)
    try:
        json = PyPIJson(package).retrieve()
        new_version = Version(json['info']['version'])
    except Exception as e:
        logger.error('Error: Failed to fetch data for {0} ({1})', package, e)
        return
    if new_version > version:
        res.put_nowait((package, version, new_version, json))

class Updater(FileManager):

    # __init__ and other methods...

    def update(self):    
        logger.info('Searching for updates')
        packages = Queue.Queue()
        data = ((packages, self.set_len, dist.project_name, Version(dist.version)) \
            for dist in self.working_set)
        pool = multiprocessing.Pool()
        pool.map(check_one, data)
        pool.close()
        pool.join()
        while True:
            try:
                package, version, new_version, json = packages.get_nowait()
            except Queue.Empty:
                break
            txt = 'A new release is avaiable for {0}: {1!s} (old {2}), update'.format(package,
                                                                                      new_version,
                                                                                      version)
            u = logger.ask(txt, bool=('upgrade version', 'keep working version'), dont_ask=self.yes)
            if u:
                self.upgrade(package, json, new_version)
            else:
                logger.info('{0} has not been upgraded', package)
        self._clean()
        logger.success('Updating finished successfully')
当我运行它时,会出现一个奇怪的错误:

Searching for updates
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/local/lib/python2.7/dist-packages/multiprocessing/pool.py", line 225, in _handle_tasks
    put(task)
PicklingError: Can't pickle <type 'thread.lock'>: attribute lookup thread.lock failed
搜索更新
线程1中的异常:
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python2.7/threading.py”,第552行,在引导程序内部
self.run()
文件“/usr/lib/python2.7/threading.py”,第505行,运行中
自我目标(*自我参数,**自我参数)
文件“/usr/local/lib/python2.7/dist packages/multiprocessing/pool.py”,第225行,在“handle”任务中
放置(任务)
PicklingError:无法pickle:属性查找线程.lock失败

多处理通过
mp.SimpleQueue
将任务(包括
检查一个
数据
)传递给工作进程。与
Queue.Queue
s不同,放入
mp.SimpleQueue
的所有内容都必须是可拾取的<代码>队列。队列不可拾取:

import multiprocessing as mp
import Queue

def foo(queue):
    pass

pool=mp.Pool()
q=Queue.Queue()

pool.map(foo,(q,))
产生此例外情况:

UnpickleableError: Cannot pickle <type 'thread.lock'> objects

在对类似问题进行了大量挖掘之后

结果还表明,任何碰巧包含threading.Condition()对象的对象永远不会与multiprocessing.Pool一起工作

这里有一个例子

import multiprocessing as mp
import threading

class MyClass(object):
   def __init__(self):
      self.cond = threading.Condition()

def foo(mc):
   pass

pool=mp.Pool()
mc=MyClass()
pool.map(foo,(mc,))
我用Python 2.7.5运行了这个程序,遇到了相同的错误:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
  File "/usr/lib64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib64/python2.7/multiprocessing/pool.py", line 342, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'thread.lock'>: attribute lookup thread.lock failed
线程2中的异常: 回溯(最近一次呼叫最后一次): 文件“/usr/lib64/python2.7/threading.py”,第811行,在引导程序内部 self.run() 文件“/usr/lib64/python2.7/threading.py”,第764行,正在运行 自我目标(*自我参数,**自我参数) 文件“/usr/lib64/python2.7/multiprocessing/pool.py”,第342行,在“handle”任务中 放置(任务) PicklingError:无法pickle:属性查找线程.lock失败 但是在Python3.4.1上运行了它,这个问题已经解决了


虽然我还没有遇到任何有用的解决方法,但对于我们这些仍然使用2.7.x的人来说

我在docker上使用python 3.6版时遇到了这个问题。将版本更改为3.7.3并解决了此问题

谢谢大家!!但现在如何填充队列?我不能让它全球化。。。我还试着让
check\u one
成为一个方法(使用这个hack:),但同样,它不起作用……我在这里找到了解决方案:。我必须使用
multiprocessing.Manager().Queue()
而不是
multiprocessing.Queue
。至于解决方法,我认为你是对的。我会修正我的代码。再次感谢你!!我知道这个问题是针对
多处理.Pool
,但是如果我有一个实际的
线程.Lock
,我该怎么办?从Python 3.4.3开始,
线程化.Lock仍然不能被pickle(尽管正如您所提到的,
线程化.Condition
)。我确认在Python 3.6.2.hmm中仍然无法对
threading.Lock
对象进行pickle处理…并且仍然在3.7版本3.6.8中,并且现在存在此问题,挖掘堆栈溢出…我在尝试将threading.RLock传递给池初始值设定项时遇到了相同的问题。在我切换到multiprocessing.RLock之后,一切都按预期进行。“multiprocessing.Pool快让我发疯了…”-这是真的…面对Python 3.7.6中的问题
Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
  File "/usr/lib64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib64/python2.7/multiprocessing/pool.py", line 342, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'thread.lock'>: attribute lookup thread.lock failed