You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程共享内存如何避免数据损坏?

多进程共享内存中保证4字节整数读取完整性的解决方案

问题核心

你当前的场景中,writer进程通过逐字节写入的方式更新共享内存中的4字节整数,这种操作不是原子的,会导致reader可能读到半更新的损坏数据。虽然macOS上未出现问题,但Windows和Ubuntu的内存模型无法保证逐字节操作的原子性,必须调整实现方式。

你的需求是允许读取历史有效值,只需保证读到的是完整的旧值或新值,无需实时同步,这种场景下原子操作是最优解,不需要使用锁(避免性能损耗)。

解决方案思路

现代CPU对对齐的32位(4字节)整数的单次加载/存储操作是原子的,即要么完整写入/读取整个整数,要么完全不操作,不会出现部分字节更新的情况。我们可以通过将共享内存映射为ctypes数组,直接操作整数类型,而不是逐字节复制,以此保证读写的原子性。

修改后的示例代码

import time
import random
import multiprocessing
from multiprocessing import shared_memory
import ctypes

def writer(rank, arr):
    index = 0
    while True:
        arr[rank] = index  # 原子赋值整个32位整数
        index += 1
        time.sleep(random.random())

def reader(arr, size):
    while True:
        # 逐个读取原子整数,或直接转成列表
        indexes = [arr[i] for i in range(size)]
        print(f"Read indexes: {indexes}")
        time.sleep(1)

if __name__ == "__main__":
    size = 10
    # 创建共享内存,大小为4*size(每个c_int占4字节)
    shm = shared_memory.SharedMemory(create=True, size=4 * size)
    # 将共享内存映射为ctypes的c_int数组
    int_array = ctypes.c_int * size
    arr = int_array.from_buffer(shm.buf)

    ctx = multiprocessing.get_context("spawn")

    processes = []
    for i in range(size):
        p = ctx.Process(target=writer, args=(i, arr))
        processes.append(p)
        p.start()

    reader_process = multiprocessing.Process(target=reader, args=(arr, size))
    reader_process.start()

    try:
        for p in processes:
            p.join()
        reader_process.join()
    finally:
        shm.close()
        shm.unlink()  # 清理共享内存

关键细节说明

  1. 原子操作保障:通过ctypes.c_int数组操作共享内存,赋值和读取都是直接操作整个32位整数,CPU会保证这类对齐操作的原子性,不会出现半写半读的损坏数据。
  2. 内存对齐:共享内存的大小设置为4*size,刚好匹配c_int数组的总大小,确保每个整数都在正确的对齐地址上,这是原子操作的前提。
  3. 无锁设计:完全符合你的性能要求,reader无需等待锁,读到的要么是writer写入的旧值,要么是新值,都是历史上的有效索引。
  4. 跨平台兼容性:这种方式依赖CPU的原子操作特性,x86、ARM等主流架构(对应Windows、Ubuntu、macOS)都支持,能保证跨平台正常运行。

内容的提问来源于stack exchange,提问作者Abdussamet TÜRKER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:26:01