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

Python多进程中整数变量正确增减的实现问题与求助

多进程共享计数原子性问题的分析与解决

错误原因

  1. 锁未跨进程共享:你在函数内创建的Lock()是每个进程独立的局部锁,不同进程的锁互不干扰,完全无法起到同步多进程操作共享变量的作用。
  2. 自增操作非原子性:_m.value += 1本质是「读取当前值→加1→写回新值」三步操作,没有同步锁的情况下,多个进程会同时读取到相同的旧值,最终导致计数重复。

修正方案

核心是使用跨进程共享的锁,包裹共享变量的读写操作,保证同一时间只有一个进程能修改计数:

  1. 通过Manager()创建共享的Lock对象,和共享计数变量一起传递给每个进程。
  2. 将自增操作与完成判断逻辑都放在共享锁的上下文内,避免并发读写导致的不一致。

修正后的代码

from concurrent.futures import ProcessPoolExecutor
import ctypes
from multiprocessing import Manager, Lock
from multiprocessing.managers import ValueProxy
import os


def calc_number(x: int, y: int, _m: "ValueProxy", lock: Lock, total_tasks: int):
    """模拟计算型任务"""

    # 模拟计算过程
    res = x**y

    # 使用跨进程共享锁同步操作
    with lock:
        _m.value += 1
        # 在锁内判断是否完成所有任务,保证读取的是最新值
        is_all_done = _m.value == total_tasks

    if is_all_done:
        print("所有任务已完成,通知Java执行整体入库操作")

    print(f"m_value: {_m.value}, p_id: {os.getpid()}, res: {res}")


def main():
    # 8组任务数据
    t1 = (100, 200, 300, 400, 500, 600, 700, 800)
    t2 = (80, 70, 60, 50, 40, 30, 20, 10)

    len_t = len(t1)

    # 创建共享变量与共享锁
    with Manager() as manager:
        m = manager.Value(ctypes.c_int, 0)
        lock = manager.Lock()

        # 多进程执行任务
        with ProcessPoolExecutor(max_workers=len_t) as executor:
            {executor.submit(calc_number, x, y, m, lock, len_t) for x, y in zip(t1, t2)}


if __name__ == "__main__":
    main()

关键说明

  • 用manager.Lock()创建的锁是跨进程共享的,能真正限制多个进程对共享变量的并发操作。
  • 将自增和完成判断逻辑放在锁内,避免出现读取到中间状态值的情况。
  • 使用Manager()上下文管理器,确保共享资源能被正确释放。

修改后m_value会依次从1递增到8,不会出现重复值,且能准确触发所有任务完成的通知逻辑。

内容的提问来源于stack exchange,提问作者Runstone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:52:56