Sea*_*ods 4 python concurrency multithreading namespaces
我正在用Python的Queue.Queue类实现一个相对简单的线程池.我有一个包含Queue实例的生成器类以及一些便捷方法,以及一个子类的使用者类threading.Thread.我基于整数为我想要在池中的每个线程("工作线程",我认为它们被调用)实例化该对象.
每个工作线程flag, data取消队列,使用自己的数据库连接对其进行处理,并将行的GUID放在列表中,以便生产者类知道作业何时完成.
虽然我知道其他模块实现了我编码的功能,但我编码的原因是为了更好地理解Python线程的工作原理.这让我想到了我的问题.
如果我将任何东西存储在函数的命名空间或类的__dict__对象中,它是否是线程安全的?
class Consumer(threading.Thread):
def __init__(self, producer, db_filename):
self.producer = producer
self.conn = sqlite3.connect(db_filename) # Is this var thread safe?
def run(self):
flag, data = self.producer.queue.get()
while flag != 'stop':
# Do stuff with data; Is `data` thread safe?
Run Code Online (Sandbox Code Playgroud)
我认为两者都是线程安全的,这是我的理由:
__dict__都会创建一个新类.在上面概述的场景中,我认为任何其他对象都不会引用此对象.(现在,如果我使用join()功能,情况可能会变得更复杂,但我不是......)global,所以我不明白任何其他对象如何引用函数变量.这篇文章在某种程度上解决了我的问题,但对我来说仍然有点抽象.
在此先感谢您为我清理这个问题.
你是对的; 这是线程安全的.局部变量(您称之为"函数名称空间"的变量)始终是线程安全的,因为只有执行该函数的线程才能访问它们.只要实例不跨线程共享,实例属性就是线程安全的.由于使用者类继承自Thread,因此它的实例肯定不会在线程之间共享.
这里唯一的"风险"是数据对象的值:理论上,生产者在将数据对象放入队列后可能会保留数据对象,并且(如果数据对象本身是可变的 - 请确保您理解"可变"的内容)意味着)可以在消费者使用它时改变对象.如果生成器在将数据对象放入队列后单独保留数据对象,则这是线程安全的.