本想让程序执行加速,却走上了bug翻车之路

软件测试的艺术-第三节-002 当不同模块对同一数据结构的理解不同时,就像国际会议上没有翻译——每个人都以为自己理解正确,实则鸡同鸭讲。明确定义头文件或使用IDL(接口定义语言)可以避免这类问题。 阅读详情

本想让程序执行加速,却无意中走上了bug之路

python中的threading

在日常的python开发中,经常会碰到使用threading模块提升程序执行效率的场景。但今天却遇到了一个翻车场景,所以赶紧拿出来分享给大家。
省略掉业务功能,来举一个场景出发的demo吧:

import time

def do_something():
    time.sleep(1)

class PersonShow:
    def __init__(self):
        self.current_name = None

    def show(self, user):
        self.current_name = user
        # do something
        do_something()
        print(self.current_name)

f = PersonShow()

for name in ["大黄", "小花", "旺财", "小强"]:
    f.show(name)

output:
    大黄
    小花
    旺财
    小强

程序很简单,我们通过实例化PersonShow的类,然后遍历姓名列表,执行show方法时将姓名赋值给current_name,之后在show方法中调用do_something函数,最终打印current_name字段。简直不要太简单的一段代码。
现在,我们觉得for循环依次执行效率太低了,想通过threading的方式进行多线程执行,该如何修改呢?很简单...

from threading import Thread
    ...
for name in ["大黄", "小花", "旺财", "小强"]:
    t = Thread(target=f.show, args=(name,))
    t.start()

我们导入threading模块后,将for循环内部改为多线程执行,so easy啊。但真的没问题么?大家思考一分钟...

问题分析

上面的代码加入多线程后,执行的结果会是什么,大家是否思考过了?
答案是:

output:
    小强
    小强
    小强
    小强

为什么会得到这样的结果呢?这其实是一个很经典的多线程问题。
我们在执行do_something函数时,等待了一秒,但一秒对于计算机来说能做的事情太多了。别说四个名字、四十四百个也不够塞牙缝的。
当使用了threading执行代码后,线程1刚刚完成赋值,还在执行do_something时,线程二、三、四已经创建完成并开始执行。这样导致的结果是,线程1的do_something函数执行完成后,current_name已经被线程四修改为了小强,如此依次打印,导致最终的current_name输出均为小强。那么遇到这种问题,该如何解决呢?

线程锁不是万能的

一般遇到这种多个线程存在互相影响的问题时,大家第一时间想到的是通过线程锁解决冲突。
但很多情况下,尤其较为简单的场景时,添加了线程锁,你的多线程就毫无作用了。比如这道题,想添加线程锁,只能在self.current_name = user这一步操作,等待打印完成之后释放锁。那多线程还有什么存在的意义?此时,我们更多该考虑的是线程安全。

线程安全

谈到线程安全,字面意思比较好理解,尤其针对这道题,就是把current_name独立分配给各自的线程么。但这样应该如何操作呢?让我们现在通过一个最笨的办法解决冲突。

for name in ["大黄", "小花", "旺财", "小强"]:
    f = PersonShow()
    t = Thread(target=f.show, args=(name,))
    t.start()

我们在每次for循环的时候,都实例化出来一个f的对象不就解决了该问题么?是解决了,但这样要造成大量的空间浪费。那么有什么更好的解决办法呢?

threading.local

threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,如果在另外一个线程里面再次进行赋值,那么会在另外一个线程单独创建内存空间来存储,也就是说在不同的线程里面赋值 不会覆盖之前的值,因为每个线程里面都有一个单独的空间来保存这个数据,而且这个数据是隔离的,其他线程无法访问。
我们可以通过如下方式使用:
当变量在代码最外层单独定义时:
localVal = threading.local()
而当变量第一在类中时,我们可以将该类继承local,最开始的代码最终可以修改为:

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @微信号   : King_Uranus
# @公众号    : 清风Python
# @GitHub   : https://github.com/BreezePython
# @Date     : 2020/09/06 11:50:42
# @Software : PyCharm
# @version  :Python 3.7.3
# @File     : threading_bug.py
import time
from threading import Thread, local

def do_something():
    time.sleep(1)

# 将该类继承threading.local,实现线程安全
class PersonShow(local):
    def __init__(self):
        self.current_name = None

    def show(self, user):
        self.current_name = user
        # do something
        do_something()
        print(self.current_name)

f = PersonShow()

for name in ["大黄", "小花", "旺财", "小强"]:
    t = Thread(target=f.show, args=(name,))
    t.start()

output:
    大黄
    小花
    旺财
    小强

以后遇到这种多线程执行时的线程安全问题,一定要记得使用threading中的local方法!

The End

期待你关注我的公众号清风Python,如果你觉得不错,希望能动动手指转发给你身边的朋友们。
我的github地址:https://github.com/BreezePython

AI写代码总翻车?Matt Pocock的这套Skills可能才是解药 用AI写代码的人,大概都经历过这种崩溃——你让Agent写个功能,它一顿操作猛如虎,结果跑不通;改了一遍又一遍,还是不对;好不容易跑通了,代码已经是一坨屎山。今天推荐的这个项目,就是来解决这件事的。 阅读详情

相关推荐

数据结构实验1.2—高精度计算PI值(西工大)

这是数据结构第二题的题目,是让我们根据用户的需求来计算派的值 这是题目的详细描述,刚看到这道题的时候,我是真的头大,完全没有思路,于是查找了一些大佬的笔记后才开始编写 这是我在写这些代码是所运用到的数学反三角函数幂次展开式的知识。 下面是正确的代码以及我的一些见解,和需要注意的一些地方。希望能对你有所帮助。如有更加精简的算法,请在评论区留下你的算法!!!谢谢!!! #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdl

abcdef0623的博客 5831

本跳转程序靠bug运行,请不要优化

来源:公众号【鱼鹰谈单片机】作者:鱼鹰OspreyID :emOsprey图片来源于网络绝大多数产品开发,软件一般都会设计成 boot + app 的形式,这是方便后续软件更新,否则更新会变成一个很麻烦的事情。网上随处可见的跳转程序大概如下:#define APP_START_ADDR 0x08040000 voidjump2app() { typedefvoi...

EmbeddedOsprey 1426

TBtools的序列提取步骤

本教程详细介绍了如何使用TBtools软件从原来的FASTA序列中提取特定的DNA序列。

weixin_47509995的博客 1万+

学了编程却写出错误代码?程序运行结果与想象不符?当bug出现时该何去何从,别担心,这篇文章统统告诉你!手把手带你调试代码,让bug原形毕露!

【手把手带你搞定】实用调试技巧什么是bug 之前我们对C语言的知识进行了一一的讲解,但是当我们自己真正写代码的时候,又会发现很多问题,比如程序运行时崩溃、程序运行的结果不是我们想要的等等,虽然代码已经能够跑起来了,但是依然不是理想中的状态。 这时候应该怎么办呢? 别急,现在立即教你使用调试技巧。 手把手带你搞定bug。 什么是bug 大家看看下面这张图: 这是世界上的第一个bug。 ...

Stella-F的博客 3847

实战解析:从Innovus到Calibre的LVS错误排查全流程

本文详细解析了从Innovus到Calibre的LVS错误排查全流程,涵盖物理验证关键步骤与工具链协同。通过实战案例分享,重点解决器件不匹配、连接性错误等常见问题,并提供GDS导出规范、网表修正策略等实用技巧,帮助工程师高效完成芯片设计物理验证。

9o8p7i6u5y的博客 1037

即梦文生视频逆向接口部署使用

有的小伙伴不知道这个地址如何填写,你可以理解是步骤3上提供的 服务器或者本地电脑IP 地址(不要写 http://127.0.0.1 或者http://localhsot ) 是 (192.168.XXX.XXX 参考)

weixin_44245188的博客 3185

java连接SQL Server数据库失败学习小结

使用java连接数据库失败的几种情况 这几天在练习一个java项目连接数据库时遇到了错误,如下: 于是对错误进行百度,发现是SQLsever的网络配置协议TCP/IP被禁用了,如下: 于是立刻变更状态为已启用,启用之后服务器还需重启才会生效,在重启后重新启动程序连接数据库又一次失败,如下: 经过百度发现是因为数据库中用户的登录状态为禁用所以无法访问 ...

m0_51145154的博客 3484

AutoCAD2014与ObjectARX开发环境搭建实战指南

本文提供了一份详细的AutoCAD2014与ObjectARX开发环境搭建实战指南。内容涵盖从AutoCAD2014、Visual Studio 2010及ObjectARX 2014 SDK的版本匹配与环境准备,到Wizard安装、编码问题解决、Visual Studio配置,并最终通过一个完整的绘图命令开发示例,手把手引导开发者创建并加载第一个可运行的ObjectARX插件,为后续深入开发奠定坚实基础。

weixin_28475533的博客 288

程序员遇到bug时常见的30种反应

本文由 伯乐在线 - JingerJoe 翻译自 hongkiat。   开发应用程序是一项压力很大的工作,人无完人,工作中遇到bug是很正常的事,有些程序员会生气,沮丧,郁闷,甚至泄气,也有一些程序员则会比较淡定。如何进行修复bug的过程,是值得我们好好推敲的。 我想分享一些有关程序员在努力修复bug时常说的话和冒出的想法。当氛围变得紧张的时候,这些话就会显得轻松幽默。最终,bug也会...

ミ∩_∩ミ 1436

锂电池寿命预测 | Python实现基于LSTM长短期记忆神经网络的锂电池寿命预测

锂电池寿命预测 | Python实现基于LSTM长短期记忆神经网络的锂电池寿命预测

算法如诗的博客 1902

Linux 配置 multipath 多路径

每天一个 DBA 小知识,助你更进一步!

LuciferLiu_DBA 3298

一个bug引发对小程序运行原理的思考

一个bug引发对小程序运行的一点点思考 最近遇到一个小程序的bug,问题不大很快解决,但是之后在看小程序运行原理的文章中,回想起这个bug,突然意识到这个bug出现的原因。通过简单讲讲 bug 出现的场景,引出一点点我对小程序运行的认识。 bug场景 在 onLoad 周期有一个循环计时器(setInterval),animation 是循环计时器的函数,内置一个一次性计时器(setTi...

耐得住寂寞也是一种境界 1272

YOLOv11改进 | 主干/Backbone篇 | 轻量级移动端网络ShuffleNetV2(附代码+修改教程)

本文给大家带来的改进内容是ShuffleNetV2,这是一种为移动设备设计的高效CNN架构。其在ShuffleNetV1的基础上强调除了FLOPs之外,还应考虑速度、内存访问成本和平台特性。(我在YOLOv11n上修改该主干降低了GFLOPs,但是参数量还是有一定上涨,其非常适合轻量化的读者来使用,同时精度也有一定程度的上涨)。本文通过介绍其主要框架原理,然后教你如何添加该网络结构到网络模型中。

Snu77的博客 3387

for循环改为多线程方式进行执行_本想让程序执行加速,却走上了bug翻车之路

python中的threading在日常的python开发中,经常会碰到使用threading模块提升程序执行效率的场景。但今天却遇到了一个翻车场景,所以赶紧拿出来分享给大家。省略掉业务功能,来举一个场景出发的demo吧:import timedef do_something(): time.sleep(1)class PersonShow: def __init__(sel...

weixin_42160645的博客 1096

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

网盘变速工具:全平台突破限速,免费开源,百倍加速亲测不翻车

亲测下 4GB 的设计素材,之前要 6 小时,现在 1 小时 40 分钟下完,流量监测软件里明明白白显示着实时速率,比客户端界面显示的 “100kb/s” 诚实多了。绿色版 10MB 大小,EXE 文件双击就开,机械革命笔记本上跑起来没卡顿,界面就两部分:调倍速的滑块和系统进程列表,比 CE 的复杂界面好懂 10 倍。

linan777的博客 1350

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

本地小模型实测:Gemma Coder 离线代码生成能力与翻车复盘

在数据隐私和离线开发需求日益突出的今天,本地小模型成为开发者关注的热点。这类参数量较小的开源模型通过 Ollama 等工具即可部署在个人电脑上,不依赖云端 API,以较低硬件成本实现代码生成、脚本补全和简单算法实现等能力。其核心价值在于数据不出本机、支持内网环境、按需高频调用,特别适合处理脚本片段、单元测试与代码解释等任务。然而,本地小模型也客观存在能力边界,如编造 API、代码截断、上下文失忆等问题。本文基于对 Gemma 系列代码向模型的完整实测,系统梳理部署流程、编码任务表现、高频翻车原因与提示词优化

weixin_28678151的博客 329

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Pytorch翻车记录:单卡改多卡踩坑记!

作者|哟林小平 编辑| 极市平台点击下方卡片,关注“自动驾驶之心”公众号ADAS巨卷干货,即可获取点击进入→自动驾驶之心【全栈算法】技术交流群后台回复【领域综述】获取自动驾驶全栈近80篇综述论文!导读本文记录了作者尝试单卡改多卡加速的过程中出现的bug记录:一是继承DistributedSampler的漏洞百出,二是master进程无法正常结束,作者详细的阐述了出错的细节以及给出了修改的...

CV_Autobot的博客 637

Win11再度翻车,官方承认更新的承诺为吹牛

win11更新bug没完没了,来看看解决方法

meiyimin的专栏 823

Godot 数学库一次讲透:5 类移动朝向翻车,一篇修好

你的角色明明向右跑,却在过弯的瞬间突然转了 180°、脸朝向了墙;3D 相机越转越抖,最后连上下方向都翻了。这些不是场景或资源的 bug,全是数学没算对。Godot 数学库(向量、变换矩阵、点积叉积、四元数)就是这 5 类翻车的标准解法。 ## 移动和朝向对不上:Godot 向量的方向与归一化 **现象。** 按 W 走直线是全速,按 W+D 斜着走却明显比直线快;角色的朝向总慢半拍,像在每一

gitblog_00665的博客 239

算法Bug识别能力成长路径:从现象归因到机制预判

机器学习中的算法Bug并非代码错误,而是模型决策系统性偏移的隐性缺陷,其本质是数据、模型与业务目标之间的深层矛盾。理解这类Bug需超越传统调试思维,从基础概念出发,把握其在数据漂移、特征编码、损失函数错位等环节的生成原理;技术价值在于将不可见的‘效果异常’转化为可观测、可量化、可干预的信号链;典型应用场景覆盖电商推荐、工业质检、信贷风控等对鲁棒性要求严苛的工程领域;本文聚焦工程师识别算法级缺陷的能力演进规律,结合数据分布信号、梯度健康信号等核心热词,系统拆解从症状识别、根因锚定到机制预判的三阶跃迁路径。

dglf54292的博客 400

硬件加速与软件加速的选型之道:从瓶颈分析到性能上限

计算机系统性能优化的本质,是在理解瓶颈的前提下选择最合适的加速手段。硬件加速如FPGA、ASIC,通过定制并行数据通路换取出色的吞吐与能效,但开发周期长、灵活性差;软件加速如SIMD向量化、编译优化与运行时调优,则以低成本支持快速迭代,却受限于CPU架构与内存带宽。二者并非对立,而是同一问题的不同解法。实际工程中,需要从性能剖析、量化模型、成本约束与团队能力出发,建立科学的决策框架。本文结合视频处理、AI推理等典型场景,对比硬件与软件加速的技术栈、性能收益和踩坑经验,并探讨FPGA与GPU等混合方案的任务划

weixin_30730053的博客 391

那些年被编程纠正的认知误区:程序不是你想的那样

在编程学习与软件开发中,许多初学者常凭生活直觉理解程序行为,却遭遇各种反直觉现象。比如程序并非简单从上到下执行,缓冲区与异步机制会影响输出顺序;变量名长短并不影响运行时内存,可读性才是工程关键;文件删除不等于数据消失,逻辑删除与数据残留需谨慎处理;数值并非越大越好,整数溢出与浮点精度问题常引发线上事故。这些认知误区的本质,是旧有心智模型与真实计算机系统不匹配。理解缓冲、类型、存储等基础原理,掌握最小复现、读官方文档等方法,能帮助开发者逐步建立准确的计算思维,提升代码质量与问题排查能力。本文以生动案例串联典型

weixin_33834075的博客 368

音视频转换实战指南:从4K转码翻车到批量自动化的完整闭环

凌晨两点,一段 4K 直播回放在转码到 62% 时第三次崩溃。换了参数重试,依旧在同一个进度点倒下——直到我意识到,问题不在参数,而在引擎。如果你也被这类"玄学翻车"折磨过,**OpenConverter**——这款基于 FFmpeg 源码、Qt 框架与 BMF 框架构建的开源**音视频转换**工具,也许能帮你把同样的弯路一次走完。下文不写安装流水账,只讲清楚三件事:引擎怎么选、参数怎么调、批量怎

gitblog_00472的博客 723

【技术实践 | 工程方法】DeepSeek V4终于要来了:万亿参数、35倍推理加速

DeepSeek V4 官宣万亿参数 + 35 倍推理加速,数字好看但工程师真正关心的是显存占用、推理延迟和部署门槛。本文从公开信息出发,拆清楚 V4 到底在工程层面意味着什么:FP16 精度显存需求约 200GB,消费级显卡基本无缘;

计算机魔术师的blog 589

Codex 编程智能体实战:从自动改 Bug 到云端审 PR 的完整工作流

在 AI 辅助编程快速演进的今天,传统的代码补全工具已难以满足复杂开发需求。编程智能体(Agent)作为一种能够自主理解任务、调用工具链并执行验证的新范式,正在重塑开发者工作流。它依托大型语言模型的推理能力,结合云端沙箱、Git 操作和自动化测试,实现了从自然语言指令到可验收代码的闭环。这种技术不仅适用于个人开发者提升编码效率,更可融入团队协作场景,如自动生成提交信息、基于 Issue 创建 PR、甚至通过手机远程审阅代码。本文以 Codex 为例,深入拆解其核心原理、实用配置与真实项目中的踩坑记录,帮助开

weixin_29057163的博客 248
上一篇: 遇见一个删除文件的问题,网上的答案却都在扯淡?
下一篇: 当Python遇到zip解压炸弹,防护不到位让你泪流满面!
清风Python
博客等级 码龄7年 406粉丝 267原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值