如何包装 Python 迭代器以使其线程安全?

2024-06-25

因为有时它比围绕队列设计解决方案更实用,所以我想编写一个简单的包装器来使迭代器线程安全。到目前为止,我的灵感来自these https://stackoverflow.com/questions/1131430/are-generators-threadsafe topics https://stackoverflow.com/questions/1466676/create-a-wrapper-class-to-call-a-pre-and-post-function-around-existing-functions并提出了两个想法:

Idea 1

class LockedIterator(object):
    def __init__(self, it):
        self._lock = threading.Lock()
        self._it = it.__iter__()
        if hasattr(self._it, 'close'):
            def close(self):
                with self._lock:
                    self._it.close()
            self.__setattr__('close', close)

    def __iter__(self):
        return self

    def next(self):
        with self._lock:
            return self._it.next()

我不喜欢它的是,如果我必须指定所有可能的方法,它会变得有点冗长 - 好吧,我不能 - 例如生成器的特殊情况。另外,我可能还有一些其他具有更具体方法的迭代器,这些方法现在已被隐藏。

Idea 2

class LockedIterator(object):
    def __init__(self, it):
        self._lock = threading.Lock()
        self._it = it.__iter__()

    def __getattr__(self, item):
        attr = getattr(self._it, item)
        if callable(attr):
            def hooked(*args, **kwargs):
                with self._lock:
                    return attr(*args, **kwargs)
            setattr(self, item, hooked)
            return hooked

这更简洁,但它只能拦截调用,而不能,例如直接更改属性。 (现在隐藏这些属性以防止出现问题。)更重要的是,它使得 Python 不再将我的对象识别为迭代器!

在不创建泄漏抽象的情况下,使其适用于所有迭代器(甚至更好:所有对象)的最佳方法是什么?我不太担心不必要时的锁定,但如果你能想出一个解决方案来规避这个问题,那就太好了!


首先,你是否意识到the GIL http://wiki.python.org/moin/GlobalInterpreterLock?尝试编写多线程 Python 通常会导致运行时间比简单的单线程版本慢。

您第一次尝试使迭代器线程安全的访问似乎非常合理。您可以使用生成器使其更具可读性:

def locked_iter(it):
    it = iter(it)
    lock = threading.Lock()
    while True:
        try:
            with lock:
                value = next(it)
        except StopIteration:
            return
        yield value
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何包装 Python 迭代器以使其线程安全? 的相关文章

随机推荐

  • 从原始字节创建 bmp 文件的可移植函数? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个原始字节数组 我想从这些字节创建一个 bmp 文件 也就是说 我必须填充位图标头结构和其他内容
  • 维护动作变量的值?

    class SampleAction extends ActionSupport private Map
  • 如何在 C# 中使用 XPath 获取 SelectedNode 的数量?

    我在我的应用程序中使用 HTMLAgilityPack 我想获取 SelectedNodes 的项目 节点 计数 如下代码所示 HtmlAgilityPack HtmlDocument doc new HtmlAgilityPack Htm
  • VS2010调试问题

    好吧 奇怪的事情又发生在我身上了 今天早上 当我启动 ASP NET 应用程序时 对其进行了一些工作 现在当我尝试发布它时 我收到一个错误 我似乎找不到任何相关文档 Error 1 Unable to apply a change whil
  • 如果两个指针的地址相同,则更改其中一个指针的值

    我有一个问题 我看到两个指针的地址与这里的问题相同 两个指针的地址相同 https stackoverflow com q 19088153 1292348 蓝月亮也回答了 这让我产生了更多疑问 由于两个指针具有相同的地址 我想更改其中一个
  • SQLPlus 中的运行循环

    我制作了一个 bash 脚本 它通过 SQLPlus 连接到数据库并运行一个包含 For 循环的 SQL 脚本 如下所示 但是一旦运行它 它就会卡在循环的 BEGIN 中 如下所示 我尝试直接通过SQLPlus运行 结果是一样的 那么任何人
  • 除非登录,否则 WooCommerce 不允许将产品添加到购物车

    最近出现此问题 如果我未登录 Wordpress 我无法将产品添加到我的 WooCommerce 购物车 它按应有的方式重定向到购物车页面 但显示 购物车为空 当我以任何角色的用户身份登录时 效果都很好 我搜索了一下 发现了这个线程 htt
  • Flutter:后台中的 SVG 图像抛出错误

    我必须将 SVG 图像保留在背景中并将文本保留在顶部 当我保留 Flutter SVG 包中的 SVG 图像时 出现了这样的错误 I flutter 24437 Unsupported operation Could not resolve
  • iOS7 色调颜色仅在呈现并关闭另一个 ViewController 后才起作用

    我在 iOS7 中遇到了一个非常奇怪的色调问题 当我第一次加载时遇到问题的 ViewController 时 所有色调都是浅灰色 就好像一切都处于非活动状态或位于使屏幕变暗的 UIAlertView 后面 这些按钮仍然处于活动状态并且工作正
  • C# - 将 WPF Image.source 转换为 System.Drawing.Bitmap

    我发现很多人都在转换BitmapSource to a Bitmap 但是关于ImageSource to Bitmap 我正在制作一个成像程序 我需要从显示的图像中提取位图Image元素 有谁知道如何做到这一点 EDIT 1 这是一个用于
  • Django:设置为 30 秒后过期的 Cookie 实际上会在 30 分钟后过期?

    这是我的代码 def update session request if not request is ajax or not request method POST return HttpResponseNotAllowed POST u
  • 使用 sed 更改 /etc/fstab

    我想改 etc fstab在脚本内 我想添加acl属性到根分区 One fstab行条目如下所示 UUID 730aee20 52b7 4920 75cd d0d995ef2445 ext3 errors remount ro 0 1 我想
  • Paypal IPN 并行支付问题

    我正在用这个http www binpress com app paypal adaptive payments pro codeigniter library 140 http www binpress com app paypal ad
  • 如何修改Open Shift中的节点启动命令?

    我使用 ES6 和 babel node 来创建我的应用程序 并且我要求我的应用程序以命令启动babel node app js 此命令列在我的 package json 中的 script start 中 因此命令 npm start 运
  • 在 R heatmap.2 中移动颜色键(gplots 包的功能)

    我现在阅读了 heatmap 2 帮助手册几次 并且在各种在线教程中我也没有读到有关将颜色键移动到不同位置的方法 现在 我想知道这是否可能 如果您使用 gplots 包中的 heatmap 2 函数 则默认情况下颜色键位于左上角 中每个元素
  • 使用两个不同颜色的数据集创建 matplotlib 热图

    我目前有两个大数据集 我想对它们进行比较 我把它们分开 一个是红色的 一个是蓝色的 但是我想并排显示红色和蓝色 我该怎么办 我当前的代码是 column labels list heatmap ylabels row labels list
  • 在 NHibernate 中标准化 EnumStringType

    我目前正在 NHibernate 中使用枚举 映射如下 public enum UploadMethod Java Silverlight Gears Flash class UploadMethodType EnumStringType
  • 如何在使用代理服务器访问 Internet 的 Windows 计算机上安装 Rails?

    我是 ruby 方式的忠实粉丝 然而今天它妨碍了我 安装rails的事实上的方法 我在WinXP机器上以域用户身份运行 是 下载并安装 ruby 一键安装程序 type gt gem install rails在命令提示符下 步骤 2 失败
  • Vue CLI 3 不会将供应商转换为 ES5

    我们有一个 vue cli 3 项目 它工作得很好并且编译没有问题 事实上 我们必须支持仅支持 ES5 代码的旧浏览器 在项目中我们集成了一些用ES6编写的外部库 reconnecting websocket是一个例子 Problem 使用
  • 如何包装 Python 迭代器以使其线程安全?

    因为有时它比围绕队列设计解决方案更实用 所以我想编写一个简单的包装器来使迭代器线程安全 到目前为止 我的灵感来自these https stackoverflow com questions 1131430 are generators t