讲师中心 微信公众号
AI工具推荐 视频效率加速

Python 如何安全地在多线程环境下累加计数器(不加锁)

落枫小哥_7751

落枫小哥_7751

发布时间:2026-01-17 12:47:08

|

470人浏览过

|

来源于php中文网

原创

不依赖传统互斥锁的安全累加方法有五种:一、threading.local实现线程私有计数;二、queue.Queue消息传递由单线程汇总;三、Semaphore伪原子累加(依赖私有属性);四、multiprocessing.Value利用底层原子指令;五、numpy+ctypes/numba调用平台原子原语。

python 如何安全地在多线程环境下累加计数器(不加锁)

如果您在 Python 多线程程序中直接对共享整数变量执行 += 操作,将面临竞态条件导致计数丢失的问题。以下是几种不依赖传统互斥锁(如 threading.Lock)实现安全累加的可行方法:

一、使用 threading.local 实现线程私有计数器

该方法为每个线程分配独立的计数器副本,彻底避免共享冲突,适用于各线程只需维护自身计数值、最终无需全局汇总的场景。

1、导入 threading 模块并创建 local() 实例。

2、在线程函数内部,通过 local 实例的属性访问当前线程专属的计数器变量。

立即学习“Python免费学习笔记(深入)”;

3、对该变量执行任意次数的 += 操作,均不会影响其他线程的值。

4、主线程无法直接读取各线程的 local 计数器,如需汇总,须由各线程主动上报结果。

二、使用 queue.Queue 替代共享变量

将累加操作转化为“发送增量指令”的消息传递过程,由单一线程(通常是主线程)顺序消费并更新全局计数器,消除并发写入。

1、初始化一个 threading.Queue 实例用于承载增量值。

2、每个工作线程计算完本地增量后,调用 queue.put(delta) 将数值入队。

3、主线程启动一个专用消费者循环,持续调用 queue.get() 获取增量并累加到全局变量。

4、所有线程完成任务后,向队列发送结束信号(如 None),消费者检测到后退出循环。

三、使用原子操作类型——threading.Semaphore(伪原子累加)

利用信号量的内部计数器作为累加载体,其 acquire() 与 release() 方法底层由 C 实现且具有原子性,可间接达成安全递增。

1、创建初始值为 0 的 threading.Semaphore(0) 实例。

windows-screenshot-ocr
windows-screenshot-ocr

Windows全屏截图(自动标记鼠标位置)+ 原生OCR文字识别。本地运行,无需联网和API Key,适用于截图分析和自动化OCR场景。

下载

2、每次需“加 1”时,调用 semaphore.release() —— 此操作原子性地使内部计数器加 1。

3、获取当前总和时,需通过反射访问其私有属性 _value(仅限 CPython 实现,不可跨版本依赖)。

4、注意该方式仅支持整数累加,且 _value 属于未公开 API,运行时行为无保障。

四、使用 multiprocessing.Value(配合 threading)

借助 multiprocessing 模块提供的进程共享内存对象,其内部已封装原子操作,可在多线程中安全读写。

1、创建 multiprocessing.Value('i', 0),指定类型码 'i' 表示有符号整型。

2、各线程调用 value.value += 1 时,底层会触发原子的 CPU 指令(如 x86 的 LOCK XADD)。

3、无需显式加锁,所有线程对 value.value 的写入天然串行化。

4、该对象支持 ctypes 支持的所有基础类型,但仅限于数值类共享变量。

五、使用 numpy.ndarray 配合 atomic 操作(需 numba 或 ctypes 辅助)

纯 Python 中 numpy 数组本身不提供原子性,但可通过 ctypes 绑定到共享内存,并调用平台特定的原子指令实现。

1、分配一块 ctypes.c_int32 类型的共享内存区域。

2、使用 numpy.frombuffer() 将其映射为 int32 数组。

3、借助 numba.njit(parallel=True) 或手写 ctypes 函数调用 OS 提供的原子加法(如 Windows 的 InterlockedAdd,Linux 的 __atomic_fetch_add)。

4、此方案绕过 GIL 且性能极高,但要求开发者熟悉底层原子原语及平台差异。

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

相关专题

更多
全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

5085

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

2150

2025.09.18

c++ 全局变量
c++ 全局变量

本专题整合了c++全局变量的使用、定义、作用域等等内容,阅读专题下面的文章了解更多详细内容。

199

2026.03.17

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4658

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

1309

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

443

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

579

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

429

2026.02.06

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn