multiprocessing.Pool - PicklingError:无法 pickle :属性查找 thread.lock 失败

2023-12-03

multiprocessing.Pool让我发疯了...
我想升级许多软件包,对于每一个软件包,我都必须检查是否有更高的版本。这是由check_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

多处理传递任务(其中包括check_one and data)通过一个工作进程mp.SimpleQueue。不像Queue.Queues,所有东西都放在mp.SimpleQueue必须是可挑选的。Queue.Queues 不可选择:

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

Your data包括packages,这是一个 Queue.Queue。这可能就是问题的根源。


这是一个可能的解决方法:Queue用于两个目的:

  1. 找出大概的大小(通过调用qsize)
  2. 存储结果以供以后检索。

而不是打电话qsize,为了在多个进程之间共享值,我们可以使用mp.Value.

我们可以(并且应该)只从调用中返回值,而不是将结果存储在队列中check_one. The pool.map将结果收集到自己制作的队列中,并将结果作为返回值返回pool.map.

例如:

import multiprocessing as mp
import Queue
import random
import logging

# logger=mp.log_to_stderr(logging.DEBUG)
logger = logging.getLogger(__name__)


qsize = mp.Value('i', 1)
def check_one(args):
    total, package, version = args
    i = qsize.value
    logger.info('\r[{0:.1%} - {1}, {2} / {3}]'.format(
        i / float(total), package, i, total))
    new_version = random.randrange(0,100)
    qsize.value += 1
    if new_version > version:
        return (package, version, new_version, None)
    else:
        return None

def update():    
    logger.info('Searching for updates')
    set_len=10
    data = ( (set_len, 'project-{0}'.format(i), random.randrange(0,100))
             for i in range(set_len) )
    pool = mp.Pool()
    results = pool.map(check_one, data)
    pool.close()
    pool.join()
    for result in results:
        if result is None: continue
        package, version, new_version, json = result
        txt = 'A new release is avaiable for {0}: {1!s} (old {2}), update'.format(
            package, new_version, version)
        logger.info(txt)
    logger.info('Updating finished successfully')

if __name__=='__main__':
    logging.basicConfig(level=logging.DEBUG)
    update()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

multiprocessing.Pool - PicklingError:无法 pickle :属性查找 thread.lock 失败 的相关文章

随机推荐

  • WPF 图像:.Source = Clipboard.GetImage() 未显示

    这个简单的程序不起作用 图像没有出现在窗口中 namespace ClipBoardTest public partial class MainWindow Window public MainWindow InitializeCompon
  • 如何创建带有数据字段的 Java 类

    我正在上一门编程课 该课为我提供了一个项目 但我不知道从哪里开始 希望有人能把我推向正确的方向 我只发布该项目的一部分 以便有人可以向我展示一些代码 以了解它是如何完成的 因为我之前参加过编程课程 但我缺乏实践 创建一个名为 Registr
  • 如何通过javascript设置没有id的textarea的值?

    通常我们运行 javascript 代码来设置任何值 document getElementById id name value 但我有一个这样的页面 div div class class name div div
  • 是否可以在多选下拉列表中设置限制?

    我在我的网站中使用了多项选择下拉列表 这工作正常 我们可以从该列表中选择多个选项 但我只想从该列表中选择 3 个选项 是否可以为此设置限制 我正在使用来自的代码http www aleixcortadellas com main 2009
  • Git 命令显示 .gitignore 忽略了哪些特定文件

    我正在接触 Git 并遇到以下问题 我的项目源树 src refs vendor 我的供应商分支中有代码 当前为 MEF 我将在那里进行编译 然后将引用移至 src refs这就是项目从中获取它们的地方 我的问题是我有我的 gitignor
  • 如何使用jquery获取输入是否具有焦点[重复]

    这个问题在这里已经有答案了 如何使用jquery获取html的输入标签是否具有焦点 如果输入 图像等标签具有焦点 则 keydown 事件将适用于表单 但它不会工作 它的重点是形式 而不是任何标签 如输入 图像等 我该如何解决这个问题 请帮
  • 将 BCD 转换为二进制的最有效方法

    我有下面的代码将 32 位 BCD 值 以两个 uint 半部分提供 转换为 uint 二进制值 提供的值最大可达 0x9999 形成最大值 0x99999999 有没有更好 即更快 的方法来实现这一目标
  • for line in File 是否读取整个文件

    以下代码是为每个循环读取一行 还是在开始迭代之前先将整个文件读入内存 for line in f print line 我的目的是从文件中读取一行 你无法确定 你所能知道的就是它会return一次一行 这Python 标准库文档 says
  • 将多行连接成一行

    我现在正在学习SQL on SQL Server 我需要将多行连接成一列 我已经寻找过示例 但没有找到可以用来满足我的需求的示例 Country ProjectTA Complexity TID Sites Inits Name Unite
  • 主机和 GPU 上 CUDA 添加的不同结果

    我有一个函数可以获取彩色图片并返回其灰色版本 如果我在主机上运行顺序代码 一切都会完美运行 如果我在设备上运行它 结果会略有不同 与正确值相比 1000 个像素中的一个像素不是 1 就是 1 我认为这与转换有关 但我不确定 这是我使用的代码
  • html5 视频标签在 Android PhoneGap 中不起作用

    我已经在 android PhoneGap 中创建了应用程序 我想使用 html5 视频播放器播放视频 我的代码是
  • 追加时返回 null 的字符串

    我的任务是创建一个猜词游戏 您只有 5 次尝试猜测该单词的机会 用户一次输入一个字母 试图找出我的秘密单词 果汁 但您应该使用提示单词构造 每次猜测都会用正确的字母替换星号 如果正确 输出应该是这样的 欢迎来到猜词游戏 您有 5 次机会尝试
  • SQL Server 2008 中从数据库到数据集的位数据类型到枚举类型的映射

    我有一个表 其中有一列Xyz它有bitSQL Server 2008 中的数据类型 我通过数据适配器从表中获取值 并将其存储在DataSet and a DataGridView将显示来自的内容DataSet 在网格视图中 对于列Xyz 显
  • 鼠标光标位图

    我试图从鼠标光标获取位图 但在下一个代码中 我无法获取颜色 CURSORINFO cursorInfo 0 cursorInfo cbSize sizeof cursorInfo if GetCursorInfo cursorInfo IC
  • 如何在resilience4j中配置retryOnResultPredicate?

    我想将failAfterMaxAttempts设置为true以在最大重试结束时获得MaxRetriesExceededException 根据文档 我们需要使用failAfterMaxAttempts设置retryOnResultPredi
  • iOS7 itms-services 方案不起作用?

    我有一个内部应用程序 通过本地 WiFi 分发 在发布页面有一个像这样的链接 itms services action download manifest url http 192 168 1 231 app plist houseApp
  • Python OpenCV 从相机流式传输 - 多线程、时间戳

    我在 Raspberry Pi 3 上运行了简单的 python 脚本 该脚本负责打开视频设备并使用 MJPEG 将数据 800x600 流式传输到 HTTP 端点 当我收到此流时 我的 Raspberry Pi 核心之一可以 100 工作
  • 打印出带有字符的 ASCII 圆和轴

    我必须打印一个圆 将其半径 圆心的坐标作为输入 cx and cy 以及绘制它所用的字符 我为轴和圆编写了一系列 if 块 如果我单独使用它们 它们会很好地工作 但是当我将它们放在同一个方法中时 我必须只有一种方法 它们会以不期望的方式重叠
  • 使用多字符分隔符将字符串拆分为数组

    我需要将一个字符串拆分为一个数组 我的问题是分隔符是 3 个字符 例如 db2 111 oracle12cR1RAC mariadb101 我需要创建以下数组 db2 111 oracle12cR1RAC mariadb101 这种方法也提
  • :属性查找 thread.lock 失败' aria-label='multiprocessing.Pool - PicklingError:无法 pickle :属性查找 thread.lock 失败'> multiprocessing.Pool - PicklingError:无法 pickle :属性查找 thread.lock 失败

    multiprocessing Pool让我发疯了 我想升级许多软件包 对于每一个软件包 我都必须检查是否有更高的版本 这是由check one功能 主要代码在Updater update方法 我创建 Pool 对象并调用map 方法 这是