python - 在多线程环境中重用本地对象

标签 python python-multithreading

我有以下情况:

  • 多线程应用程序
  • 无法控制线程的创建。这是由框架(在本例中为 celery)管理的
  • 我有一些实例化成本很高的对象,并且不是线程安全的。让它们线程安全不是一个选择。
  • 这些对象可以在多个位置实例化,但如果我在一个已定义该对象的线程中重新实例化该对象,则应该重用该对象。

我想出了以下模式:

#!/usr/bin/env python

import threading
import time

class MyObj1:
    def __init__(self, name):
        self.name = name

local = threading.local()
def get_local_obj(key, create_obj, *pars, **kwargs):
    d = local.__dict__
    if key in d: obj = d[key]
    else       :
        obj = create_obj(*pars, **kwargs)
        d[key] = obj
    return obj

class Worker(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        myobj1 = get_local_obj('obj1', MyObj1, (self.name))
        for _ in xrange(3):
            print myobj1.name
            time.sleep(1)

def test():
    ths = [Worker() for _ in xrange(2)]
    for t in ths : t.start()

test()

在这里,我自己创建线程,因为这只是一个测试,但正如所说,在实际应用程序中我无法控制线程。

我感兴趣的是函数get_local_obj。我有几个问题:

  1. 这个逻辑能否保证对象不会在线程之间共享?
  2. 此逻辑能否保证对象不会在线程中实例化多次?
  3. 这会导致内存泄漏吗?
  4. 您对这种方法有什么一般性意见吗?对于上面建议的场景有更好的建议吗?

编辑

只是澄清一下:我的应用程序是多线程的,但创建线程的不是我。我只是创建一些对象,这些对象恰好在框架创建的线程内运行。我的一些对象不是线程安全的,因此我只需为每个线程创建一次它们。因此get_my_object

编辑

local = threading.local() 必须在全局范围内定义。

最佳答案

这个怎么样?

class Worker (Thread):
  def __init__(self):
    super(Worker,self).__init__()
    self.m_local = threading.local()

  def get_my_obj(self):
    try:
      obj = self.m_local.my_object
    except AttributeError:
      self.m_local.my_object = create_object()
      obj = self.m_local.my_object
    return obj

  def run(self):
    my_obj = self.get_my_obj()
    # ...

最后它和你的例子类似,只是更干净。您将所有线程特定的代码保留在一个地方,run 函数“不知道”有关初始化的任何信息,它使用 getter 获取 my_obj,然后 getter 创建仅反对一次。 threading.local将向您保证数据是特定于线程的 - 这就是它的工作。

我没有看到任何内存泄漏的原因。最后,你需要付出一些努力才能得到 python 中的泄漏:)

关于python - 在多线程环境中重用本地对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13989757/

相关文章:

Python 线程没有被垃圾收集

python - 一个函数中的一个函数是否会比单独定义这两个函数占用更多的 RAM 内存?

python - 使用 Lambda 函数在 S3 中创建并上传文件

python - 删除文件时检测python中的中断流

python - 在Python中使用线程更改全局变量

Python调用脚本而不等待它执行

python - 在 tkinter GUI 类的方法中运行 while 循环,同时仍然允许 UI 运算符(operator)

python - Apache NiFi : Processing multiple csv's using the ExecuteScript Processor

python - 牛顿拉夫森法用户输入和数值输出问题

python - 如何在 Python 中并行处理列表?