Python多线程内存共享方案 Python多线程共享内存的几种方式

Python多线程内存共享方式包括:1. 全局变量配合Lock确保线程安全,适用于简单数据共享;2. queue.Queue实现线程安全通信,适合生产者-消费者模型;3. threading.local为线程提供独立数据副本,避免状态冲突;4. multiprocessing.shared_memory(Python 3.8+)共享大块二进制数据如NumPy数组,需手动同步。应根据场景选择合适机制并处理线程安全。

Python多线程中,由于全局解释器锁(GIL)的存在,虽然多线程在CPU密集型任务中无法真正并行执行,但在IO密集型场景下仍具有实用价值。而在线程之间共享数据是常见需求。以下是几种常用的内存共享方式及其使用场景和注意事项。

1. 共享全局变量

最直接的共享方式是使用模块级的全局变量。所有线程都可以读写同一个变量,但由于Python对象的可变性不同,需注意线程安全。

说明: - 对于不可变类型(如int、str),直接赋值会创建新对象,其他线程不可见。 - 可变类型(如list、dict)可以在原地修改,多个线程看到的是同一对象。

建议:

  • 使用 threading.Lock 保护共享资源,避免竞态条件。
  • 示例:
    import threading
    

data = [] lock = threading.Lock()

def add_item(value): with lock: data.append(value)

t1 = threading.Thread(target=add_item, args=(1,)) t2 = threading.Thread(target=add_item, args=(2,)) t1.start(); t2.start() t1.join(); t2.join()

2. 使用 queue.Queue 实现线程间通信

queue.Queue 是线程安全的队列实现,适合生产者-消费者模型。

优点: - 内置锁机制,无需手动加锁。 - 支持阻塞操作(put/get 可设置超时)。 - 可控制缓冲区大小,防止内存溢出。

使用示例:

import queue
import threading

q = queue.Queue(maxsize=5)

def producer(): for i in range(5): q.put(i) # 自动阻塞当队列满 print(f"Produced {i}")

def consumer(): while True: item = q.get() if item is None: break print(f"Consumed {item}") q.task_done()

3. 使用 threading.local 创建线程局部存

虽然这不是“共享”,但用于避免共享冲突的一种策略:为每个线程提供独立的数据副本。

适用场景: - 需要每个线程有独立状态(如数据库连接、用户上下文)。 - 防止变量污染。

示例:

import threading

local_data = threading.local()

def process(name): local_data.name = name print(f"Hello {local_data.name}")

t1 = threading.Thread(target=process, args=("Alice",)) t2 = threading.Thread(target=process, args=("Bob",))

4. 使用 multiprocessing.shared_memory(限Python 3.8+)

虽然名字叫 multiprocessing,但从Python 3.8起,shared_memory 模块也可被线程使用,尤其适合共享大块二进制数据(如NumPy数组)。

特点: - 共享真实内存区域,节省复制开销。 - 需手动管理生命周期(创建/释放)。 - 线程间访问仍需同步机制。

示例(共享NumPy数组):

from multiprocessing import shared_memory
import numpy as np
import threading

创建共享内存

a = np.array([1, 2, 3, 4]) shm = shared_memory.SharedMemory(create=True, size=a.nbytes) buf = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf) buf[:] = a[:]

def modify_array(offset): buf[offset] += 10

t1 = threading.Thread(target=modify_array, args=(0,)) t2 = threading.Thread(target=modify_array, args=(1,)) t1.start(); t2.start() t1.join(); t2.join()

print(buf) # 查看结果 shm.close() # 使用完释放 shm.unlink() # 删除共享内存

基本上就这些常见的Python多线程内存共享方案。根据实际需求选择:简单共享用全局变量加锁,通信用Queue,隔离状态用threading.local,大数据用shared_memory。关键是处理好线程安全问题。