Python 如何在多个线程里操作同一个类实例?

假设我有一个类是这样的:

class Foo:
    def __init__(self, users)
         self.users = users # users 是一个字典

这里 users 是一个字典,key 是 user 的 id,value 记录这个 user 的某些信息。

现在需要对这个 users 进行一个循环操作,操作都是独立的,不同 id 的 user 不会相互影响。显然,使用多线程的方式可以提高效率。伪代码如下:

foo = Foo(users=users)

for key, value in foo.users.items(): do_something()

那么问题来了,如何使得多个线程能够同时操作 self.users 呢?因为操作都是相互独立的,不存在线程同步问题,该怎么做呢?


Python 如何在多个线程里操作同一个类实例?

6 回复

使用 ThreadLocal 试试


在Python多线程环境下操作同一个类实例,关键在于处理好线程间的数据竞争。Python的threading模块提供了几种同步原语来确保线程安全。

最直接的方法是使用threading.Lock。当多个线程需要修改实例的共享状态时,通过锁来保证同一时间只有一个线程能执行关键代码段。

import threading
import time

class SharedCounter:
    def __init__(self):
        self.value = 0
        self.lock = threading.Lock()  # 创建一个锁

    def increment(self):
        # 使用with语句自动获取和释放锁
        with self.lock:
            current = self.value
            time.sleep(0.001)  # 模拟一些处理时间,增大竞争窗口
            self.value = current + 1

def worker(counter, iterations):
    for _ in range(iterations):
        counter.increment()

# 创建共享实例
counter = SharedCounter()

# 创建并启动多个线程
threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(counter, 100))
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print(f"Final counter value: {counter.value}")  # 应该是500

在这个例子里,SharedCounter类有一个内部锁self.lockincrement方法使用with self.lock:来包装修改self.value的代码。这保证了即使多个线程同时调用increment,它们也会排队依次执行这段代码,避免了因为读取旧值和写入新值之间的延迟导致的数据错误。如果不加锁,最终结果很可能会小于500。

如果只是读取实例属性而不修改,通常不需要加锁。但如果存在“读-改-写”这种复合操作,或者一个线程读的时候另一个线程可能在写,那就必须用锁来保护。

总结一下,用锁来保护对共享实例状态的修改。

队列?每次一个线程只取一个

直接 map(do_something, foo.users)就好了,map 的实现可以用多进程 multiprocessing.Pool 或多线程 multiprocessing.dummy.Pool

没看懂啊。不是直接开线程么?

1 python 解释器 gil 限制 导致 cpu 密集型操作使用多线程方式无法优化

2 多线程共享全局变量,foo 是全局的变量,在子线程里面可以直接用

回到顶部