创建安全的线程

全网首发--Unet3+改进16:在不同位置添加RepLKBlock超大卷积核 本文提出了一种基于大核卷积的神经网络架构RepLKNet,旨在缩小CNN与ViTs之间的性能差距。通过重新审视CNN中的大核设计,研究证明使用少量大卷积核替代多个小核能获得更强大的性能。提出的RepLKNet采用31×31大卷积核,在ImageNet和下游任务上取得了与SwinTransformer相当或更好的结果,同时具有更低延迟。文章详细介绍了实现步骤:(1)创建RepLKBlock模块文件;(2)在模型层中添加注意力机制;(3)在UNet模型中集成RepLKBlock;(4)完成训练流程。该方法展现了 阅读详情
有人这样阐述线程与进程的区别: ² 线程:资源竞争的最小单位 ² 进程:资源分配的最小单位 这里从资源管理的角度很好的区分开了线程与进程。这里我们不去深究各个具体平台是怎么实现线程或进程的,这里我们只需要明白一点:一个进程的崩溃一般不会影响到与他跑在同一系统上的其他进程,一个线程的以外死亡却会连累与他同处一进程的其他线程。 一般系统提供注册线程的C格式的API大致如下(这里暂时不提java等语言内建任务): //FUNCTION:注册一个线程 //PARA: char* threadname 线程名 // (void*)fun(void*) 线程回调函数 // void* para 回调函数入口参数 Void Reg_Thread(char* threadname, (void*)fun(void*), void* para); //FUNCTION:注销一个线程 // PARA: char* threadname 线程名 Void Unreg_Thread(char* threadname); 这两个接口简单明了,我可以写我的低一个线程了: #define FREE(s) do{/ free(s);/ s = null;/ }while(0) Void fun(void*para) { …… while(true) { DoSomething() } } Void *para = malloc(1<<10); Reg_Thread(“偶的线程”, fun, para); …… if(我想停了这个线程) Unreg_Thread(“偶的线程”); FREE(para); …… 的确你的线程启动,或许也实现了你的某些目的,但是注意,你的代码有了隐患,这个隐患就是来自于那个注销语句。“注销?Unreg_Thread(“偶的线程”);?”是的,一个强型的线程注销可能会带来资源的泄漏。 Void fun(void*para) { void *p = malloc(1<<10);//例如你这里申请了一段资源 while(true) { DoSomething() } FREE ( p );//这里释放 } 虽然你很小心,你的那一开的内存确实随着线程的消亡丢了!因为系统提供的注销线程的API一般不会保证你的函数会正常的执行到底,事实上,上面这段代码也没有底,你那是个死循环,转不出来了。说到这里我想说明一点: ² 程序中的资源有两种:一种是由系统替你管的,他的生死轮回你不用负责,一种是系统借给你的,借人东西用完要还的,而且要完完整整的还,这是最最基本的品格。 注:这里的资源包括你动态申请的内存,你申请的信号量,你创建的线程。 如果你向上面那样做,就会丢掉人家的东西,就会让自己丧失某种品格,怎么办?修改方案吧!修改及添加代码如下: bool g_blFlag = true; //加个全局变量 #define Unreg_Thread(s) g_blFlag = false //加个宏替换掉系统给我的那个让我丧失品格的API Void fun(void*para) { void *p = malloc(1<<10);//例如你这里申请了一段资源 while(g_blFlag)//用个变量控制这个循环总行了吧 { DoSomething() } FREE ( p );//这里释放 } “这下程序总算安全的把资源释放了吧,^_^,内存终于可以安全释放,俺的品格也算保住了!” 呵呵,先别高兴的太早,隐患还没有结束! “还没有结束?” 是的,我们回过头来再去看那个注册函数吧。 …… Void *para = malloc(1<<10); Reg_Thread(“偶的线程”, fun, para); …… if(我想停了这个线程) Unreg_Thread(“偶的线程”); FREE(para);//这个时候线程真的从循环体跳出来了吗? …… 当我们把那个循环标志置成false后,我在free我申请内存的时候,偶的线程真的结束了吗?答案是:I don’t know! 是的,目前你没有办法预知这个线程到底什么时候真正退出资源竞争的舞台。我们再加点手段吧!用一个信号量来通知我们,这总可以了吧,于是我们又得到了下面的代码: bool g_blFlag = true; //加个全局变量 SEMAPHORE semaphore; #define Unreg_Thread(s) do{g_blFlag = false;/ P(semaphore);}While(0) Void fun(void*para) { P(semaphore); void *p = malloc(1<<10);//例如你这里申请了一段资源 while(g_blFlag)//用个变量控制这个循环总行了吧 { DoSomething() } FREE ( p );//这里释放 V(semaphore); } 首先我们创建了一个互斥信号量;在一进入线程执行体就先获取该信号量,退出时释放;注销动作也会等待这个信号量,然后才往下执行。安全了吗? “……?”嘀哒、嘀哒、嘀哒…… 我们的结束线程的动作跟你的思绪一样在等待,等待什么?为什么线程还是没有退出呢?再往下看: …… Void fun(void*para) { P(semaphore); void *p = malloc(1<<10);//例如你这里申请了一段资源 while(g_blFlag)//用个变量控制这个循环总行了吧 { DoSomething()//这里究竟是个什么动作呢?sleep(2分钟); } FREE ( p );//这里释放 V(semaphore); } 如果我们的函数执行体里面存在着类似于sleep(2分钟)这样的一个动作该怎么办呢?更可怕的是象网络程序中的select阻塞式等待信号量又该怎么办呢?在这种情况下,我们怎么做才能保证他更快点退出呢?我的结束线程的动作不能太让步啊!! 改写这个函数,是的用自己的一个函数来替代这个系统调用,我们刚才已经不知不觉的用宏做了不少事情,这回还是用这个易容手段来达到我们的目的! 适配如下: Void sleep(DWORD time);//假设这个是系统提供的调用 Void mySleep(DWORD time) { if(时间小于1秒)//这里是我们结束线程的等待耐心极限 { return sleep(time); } 把time拆成n个1秒 do { sleep(1秒); } while((g_blFlag)&&(--n)); } #define sleep mySleep 进行如上适配,我们用自己的函数代替了系统提供的函数,这下解决了我们的等待问题了吧,其他的也进行类似的适配就可以了^_^。 别高兴太早!隐患依旧存在: …… Unreg_Thread(“偶的线程”); …… sleep(2分钟);//我这里的确是想等两分钟啊!! 如果在你结束线程以后的其他地方的代码处,你还是想调用这个sleep又该怎么办呢?本想让它睡2分钟,它1秒就跑出来了啊!总不会在其他调用前的地方都加个g_blFlag=true;来控制它吧!怎么办?一阵手忙脚乱后又来了灵感。 #define sleep(s) if(g_blSleepFlag) / //再添加一个变量用于控制这个调用总可以了吧! mySleep(s);/ else/ sleep(s) #define Reg_Thread g_blSleepFlag = true; Reg_Thread //这个也适配一下 #define Unreg_Thread(s) do{g_blFlag = false;/ P(semaphore);/ g_blSleepFlag = false;}While(0) bool g_blSleepFlag = true;//添加这个变量 …… Unreg_Thread(“偶的线程”); …… sleep(2分钟);//我回可是调的实实在在的sleep啊!! 通过添加一个新的全局变量,又把这个小问题搞定了^_^,……安全了^_^……? 请习惯性的接下来看吧! Reg_Thread(“偶的线程1”, fun, para); Reg_Thread(“偶的线程2”, fun, para); …… if(我想停了这个线程1) Unreg_Thread(“偶的线程1”);//我仅仅是想结束线程1但是糟糕的是线程2也退出了啊!!!! …… 如果你注册类似的两个线程,当你结束其中的一个线程的时候,另一个也随着结束,但是另一个可能又是个阻塞,完了全乱套了啊#◎¥%◎#×……%※ 现在有一种感受叫做挣扎,怎么样,滋味不好受啊!究竟是哪个环节出了问题让我掉进了泥潭越陷越深呢?平日里我们经常听到的: ² 写代码,写可重用代码。 为何我的这段充满了小技巧的代码可复用性可扩展性如此的差,随便一点缺陷就要伤筋动骨…… 抱怨至此打住吧!我们继续往下看! Class MyThread { public: void Run(); void Stop(); private : bool m_blFlag; SEMAPHORE semaphore; private: virtual void PreThread(); virtual void OnThread() = 0; virtual void PostThread(); Void sleep(DWORD time) { if(时间小于1秒)//这里是我们结束线程的等待耐心极限 { return ::sleep(time); } 把time拆成n个1秒 do { ::sleep(1秒); } while((m_blFlag)&&(--n)); } static void func(void*para) { MyThread* pThis = static_cast< MyThread* >( para); If(null == pThis) { return; } pThis-> PreThread(); while(pThis ->m_blFlag) { pThis -> OnThread (); } pThis-> PostThread(); } }; 我们把它封装成一个类的架子,以面向对象的方式去启停一个线程,它里面的具体实现留待感兴趣的读者去自己尝试着填写吧!你想起什么样的任务,就由着你派生吧,你想再适配什么阻塞函数,就随你适配吧。至少在这一节我实在是不想说它还有隐患了,因为要休息一下了^_^ 总结:感觉说到头,我在试图说服一个c程序员改用c++^_^
火焰烟雾识别系统【数据集+源码+UI界面】 数据集准备:收集并标注火焰与烟雾数据。YOLOv10训练:训练YOLOv10模型来识别火焰和烟雾。实时检测:通过摄像头视频流进行实时检测,并显示检测结果。UI界面设计:用Tkinter设计简易界面,显示检测结果。完成以上步骤后,可以实现一个完整的火焰烟雾识别系统,具备实时检测与友好的用户界面。 阅读详情

相关推荐

Label Studio + SAM2分割半自动标注与yolo11训练

Label Studio + SAM2分割半自动标注与yolo11训练

schFallingCloud 1408

玩转多线程--多线程的创建与造成线程安全的原因

一个线程就是一个执行流,每个线程之间都可以按照自己的顺序执行自己的代码,多个线程之间“同时”执行多份代码。多线程编程其实也可以称作为“并发编程”。对于进程也可以实现并发编程,但是和线程相比,线程更轻量创建线程比创建进程更快销毁线程比销毁进程更快调度线程比调度进程更快调用interrupt()方法来通知,如果线程因为调用wait/join/sleep等方法而阻塞挂起,则以InerruptedException异常的形式通知。

2401_83429250的博客 2542

Revit二次开发——不启动Revit,做rvt文件数据导出

Revit二次开发——不启动Revit,做rvt文件数据导出Node.js部分调用C#端供外部调用的dllC#部分调用RevitNet.dll,做数据导出exe做外部调用dll总结功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 N

Y.Jerome的专栏 4110

Java多线程-(线程的创建,线程安全,线程状态)

1.定义一个自定义线程类继承Thread2.重写run方法(run方法是用于设置线程任务的)3.创建自定义线程类对象4.调用Thread类中的start方法(start方法:开启线程,jvm自动执行run方法)

秦淮渔火的博客 1846

深入解析NRF52832安全DFU Bootloader实现机制与蓝牙OTA升级流程

本文深入解析了NRF52832芯片安全DFU Bootloader的实现机制与蓝牙OTA升级流程。详细阐述了Bootloader的核心概念、双区升级策略、源码初始化流程以及蓝牙DFU服务的数据传输协议,并提供了从环境搭建、密钥生成到编译烧录、生成升级包的完整实战指南,帮助开发者构建安全可靠的无线固件更新系统。

weixin_29188043的博客 490

从零开始搭建多旋翼无人机:飞控系统配置全攻略(含IMU校准技巧)

本文详细介绍了从零开始搭建多旋翼无人机的飞控系统配置全流程,重点解析了IMU校准技巧。涵盖飞控硬件选型、IMU校准(加速度计、陀螺仪、磁力计)、GPS与罗盘集成方案、飞行模式配置策略及实战故障排查手册,帮助DIY爱好者提升无人机飞行稳定性与安全性。

beta5的博客 796

线程安全和创建线程

线程安全和创建线程

Cocobuhui的博客 156

黑暗中的爆破(船讯网Ais爬虫暨爬虫实战js逆向学习经验分享)

船讯网 爬虫 js逆向 python

returnadsss的博客 1575

Java多线程:线程创建、安全、同步与线程池

多线程是指在一个程序中同时运行多个独立的执行流(线程),共享同一进程的资源(如内存空间),但各自拥有独立的执行栈和程序计数器。生活类比:一家餐厅(进程)有多个服务员(线程)同时为顾客服务,共享餐厅的资源(厨房、餐具),但各自处理不同的订单。核心优势:提高程序执行效率(如后台下载文件时不阻塞UI操作)、充分利用CPU资源。当多个线程同时操作共享资源时,若无需额外同步操作就能保证结果正确,则称该资源是线程安全的。共享资源:多个线程都能访问的变量、对象、文件等(如多线程售票系统中的“剩余票数”)。

FUYY'S BLOG 988

传输线末端短路、开路、加电感的反射系数

时,频率变化约300MHz, 出现这种偏差是因为我们的计算中将电磁波传播速率默认为。时,频率变化约300MHz, 出现这种偏差是因为我们的计算中将电磁波传播速率默认为。下图为用网络分析仪实测一长度为30cm的传输线末端加一0.6uH的线圈的反射系数。下图为用网络分析仪实测一末端短路的长度为30cm的传输线的反射系数。下图为用网络分析仪实测一末端开路的长度为30cm的传输线的反射系数。末端加电感相当于在传输线末端延长了一段后末端短路,使得相位下降速率。幅度为0dB, 相位由。幅度为0dB, 相位由。

johnboat的专栏 1873

MFC Windows 程序设计[122]之树形下拉列表框(附源码)

MFC是微软公司提供的一个类库(class libraries),用以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。有很多初学MFC的小伙伴们都觉得MFC比较难学,看书吧,看了就忘了,网上的一些教程又是写的含糊不清,故而学习起来很吃力...... 故此,本专栏亲自研究,实践,由易到难,层层深入,将调试过程中所遭所遇进行详细讲解,注意事项进行一一列举,希望能够帮助到各位初学MFC的小伙伴,避免走弯路,费时费力。.........

hnjzfwy的博客 458

java多线程创建方式以及线程安全

什么是线程 线程被称为轻量级进程,是程序执行的最小单位,它是指在程序执行过程中,能够执行代码的一个执行单位。每个程序程序都至少有一个线程,也即是程序本身。 线程的状态 新建(New):创建后尚未启动的线程处于这种状态 运行(Runable):Runable包括了操作系统线程状态的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间。 等待(Wating):处于这种状态的线程不会被分配CPU执行时间。等待状态又分为无限期等待和有限期等待,处于无限期等

攻城狮 2386

【从零开始学习 SystemVerilog】1.1、SystemVerilog 概述

【从零开始学习 SystemVerilog】1.1、SystemVerilog 概述

努力,加油每一天鸭~ 1037

多线程|线程的创建、线程的状态、线程不安全、如何保证线程安全

线程的优点、线程的创建、Thread类的常用方法、interrupt()、join()、线程的状态、出现线程不安全的原因、如何保证线程安全、synchronized、volatile、等待唤醒机制

weixin_43217281的博客 269

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

如何安全的创建线程池

如何安全的创建线程池? 这个问题之所以产生,是来自于阿里的java手册中 【线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式。】 哪个对?个人觉得还是看实际的项目,当你的项目的规模不够大,随便使用都可以,但是如果规模够大,访问量,数据处理,线程的使用量都达到了一定的规模。最好是使用ThreadPoolExecutor,来规避资源耗尽的风险。 简单来说Executors来创建线程池,也是通过调用ThreadPoolExecutor,但是问题在于Executor封装的

Cui's Blog 300

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

不要使用Executors直接创建线程池,非常不安全的,阿里代码规范明确规定不能这么创建线程池的,该如何正确创建安全可靠的线程池,线程池辅助创建工具类

本人新人,技术小白一个,如果接下来的描述有什么不对的地方,欢迎批评。如果觉得可取,转发时记得点赞哟~ 目录 问题 解决方案: 重点1:线程池大小 重点2:适当的阻塞队列 无界队列 有界队列 重点3:明确拒绝策略 问题 首先,在《阿里巴巴Java开发手册》中明确指出: 【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的...

Rubik Blog 4312

IEM模型,地表粗糙度模拟

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

【线程创建及线程安全】

线程创建方式: 1. Thread01继承Thread类,重写run方法。 Thread01 t = new Thread01( ); t.start(); 2. 类 Thread01实现Runnable接口,重写run方法。 调用时:Thread01 a = new Thread01(); new Thread(a).start(); 3. 类 Thread0...

stfen的博客 231

线程的创建,启动和线程安全(线程锁)

本文介绍了Java中线程的创建、启动和线程安全的基本概念。主要内容包括:1)三种创建线程的方法:继承Thread类、实现Runnable接口和实现Callable接口,重点讲解前两种;2)线程启动方式,通过Thread类的start()方法启动;3)线程安全问题,通过银行存取款案例演示并发问题,并使用synchronized关键字实现线程同步,确保数据一致性。文章通过代码示例对比加锁前后的运行结果,直观展示线程安全的重要性。

2401_84800972的博客 593

线程学习(2)线程创建,等待,安全,synchronized

作者:Mylvzi文章主要内容:线程学习(2)前情回顾:在上一篇博客中介绍到了进程与线程的区别,以及初步了解如何在Java实现多线程编程,通过内置的Thread类来实现多线程,充分利用多核cpu资源,要充分认识到每一个线程都是一个独立的"执行流",本篇文章继续讲解和Thread有关的一些操作。

Mylvzi的博客 970

Java多线程的创建以及线程安全的解决

某一种或者多种计算机编程语言的一组指令的集合,简单理解程序就是一段静态的代码。

weixin_48817442的博客 116

Java的创建和线程安全问题

1.创建线程 创建一个线程的方法: 方法一:继承Thread类 1).创建一个类继承于Thread 类 2).重写run 方法 3).通过对象的start的方法启动线程,但不能通过run方法来启动线程 创建线程方法二 :Runable 1)创建一个类实现Runable接口 2)实现抽象run方法 3)创建实现类对象, 4)将此对象作为参数传递给...

helloworld_ddd的博客 182

C++ 创建线程与安全结束线程

C++ 创建线程与安全结束线程

qq_53044655的博客 228

6000字弄清Java的多线程如何创建及使用线程同步解决线程安全问题。

线程休眠可以让我们的程序慢下来,比方说有一个线程我们故意希望它晚一点执行,或者模拟延迟都可以使用sleep方法。我们可以看到余额出现了-10万,线程安全问题已经出现了。synchronized(同步锁){访问共享资源的核心代码。

Bew1tch的博客 1294

创建线程,Thread类常用方法,线程状态,线程安全问题

认识线程,Thread类常用方法,线程状态,线程安全问题

xaiobit_hl的博客 3125

<Java>java多线程的创建、使用以及如何解决线程安全问题

一、程序、进程和线程 二、多线程的创建 方式一:继承于Thread类 方式二:实现Runnable接口 三、Thread中的常用方法 四、线程的生命周期 例题:多窗口售票问题 五、线程同步 方式一:同步代码块 1 解决实现Runnable方法的方式的线程安全问题 2 解决继承Thread类的方式的线程安全问题 方式二:同步方法 1 使用同步方法解决实现Runnable接口的线程安全问题 2 使用同步方法解决继承Thread类的线程安全问题

小李子还挺酸的博客 1651

线程的创建方式和线程安全的实现

1、线程和进程的联系与区别

weixin_43157935的博客 592
上一篇: 关于linux的选择
下一篇: C++中const总结
manplus
博客等级 码龄22年 6粉丝 160原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值