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