- 博客(179)
- 资源 (4)
- 收藏
- 关注

转载 C++笔记之多线程编程3
本篇文章继续写线程中的join和detach。详细说明二者的区别!一、线程状态:在一个线程的生存期内,可以在多种状态之间切换,不同的操作系统可以实现不同的线程模型。定义许多不同的线程状态,每个状态还可以包含多个子状态,但大体来说,下面几种状态是通用的:1)就绪:参与调度,等待被执行,一旦被调度选中,立即开始执行。2)运行:占用CPU,正在进行中。3)休眠:暂不参与调度,等待特定事件发生。4)中止/终止:已经运行完毕,等待回收线程资源。二、线程环境:线程存在于进程之中,
2021-12-27 17:17:54
214

转载 C++笔记之多线程编程2
本篇文章,还是主要学习记录join()函数和detach()函数每个程序至少拥有一个线程,那就是执行main()函数的主线程。而多线程则是出现两个或两个以上的线程并行运行。即主线程和子线程在同一时间段同时运行。而这个过程中会出现以下几种情况:1)主线程先运行结束2)子线程先运行结束3)主线程和子线程同时结束在一些情况下,需要在子线程结束后,主程序才能结束。而一些情况则不需要等待,但需要注意一点,并不是主程序结束了其他子线程就立即停止,其他子线程会进入后台运行。一、join
2021-12-27 15:10:16
241

原创 linuxmint20.1安装一系列库
前言之前将linuxmint19.3的显卡驱动由440系列(到底是440多少我忘记了,应该是440.33)在驱动管理中升级显卡驱动版本为460,结果导致重启电脑后进不去渲染界面,一直黑屏光标闪动。后面卸载驱动,又重新安装440.64、440.86、440.100,但是全部都没法使用。之后我索性直接安装linuxmint20.1,该linux发行版是基于ubuntu20的,直接解决了这种问题,成功地安装了460.32.03的显卡驱动。新系统装好后:(1)更新软件源换为国内源(2).
2021-01-25 14:20:19
546
1

原创 linuxmint20.1 opencv4.5.0安装并在cmakelists中添加opencv库
安装教程参考:https://blog.youkuaiyun.com/qq_34907927/article/details/111647393?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.con
2021-01-21 10:53:35
500
原创 ROC、TPR、FPR的含义
AUC: 衡量模型分类能力的综合指标,值越大,模型的分类能力越强。TPR: 衡量模型对正样本的识别能力,值越大,模型对正样本的识别能力越强。FPR: 衡量模型对负样本的误判能力,值越小,模型对负样本的误判能力越弱。通过 ROC 曲线和 AUC 值,你可以全面评估分类模型的性能,并选择合适的模型进行应用。2、真阳性率(True Positive Rate, TPR)与假阳性率(False Positive Rate, FPR)的定义。
2024-09-26 16:55:24
1200
原创 模型压缩之知识蒸馏
除了前面笔记中的剪枝,知识蒸馏也是模型压缩一个重要方法之一,并且该方式是把一个复杂的大模型上学习到的知识迁移到另一个更适合部署的小模型上,在保证精度不下降的同时,实现模型压缩。
2024-09-04 15:42:02
339
原创 模型压缩之剪枝
特征图重构是一种在通道剪枝中常用的方法,旨在最小化剪枝后特征图与原始特征图之间的差异。下面是一个示例代码,展示了如何对BN层的scale factor添加L1正则化,并进行通道剪枝和微调(finetune)。:根据设定的稀疏性阈值,我们创建一个掩码(mask),只保留那些权重绝对值之和大于阈值的通道,并更新卷积层的权重和偏置。下面我写了一个简单的示例代码,展示了如何在训练过程中计算权重的稀疏性,并根据稀疏性剪掉通道。通过这种方式,我们可以根据权重的稀疏性剪掉不重要的通道,从而减少模型的复杂度和计算量。
2024-09-04 11:47:41
850
原创 caffe源码编译安装
这个宏定义,这些都是API不兼容,但是NVIDIA声明cudnn8不支持了,caffe的代码也没人去更新了,所以不能指望NVIDIA或者berkeley,只能自行修改。最后在build文件夹下找到Caffe.sln文件,用VS2015打开,然后右键ALL_BUILD进行生成,等几分钟后编译完,(注意:这个要自己调整路径,我这边懒得调整了,所以你们看是报错了路径问题,就不再修改了,直接用下文的命令处理即可)要按照官网来转成LMDB格式,那么需要能在windows下运行.sh的程序, 需要安装。
2024-03-31 00:47:31
928
原创 libtorch c++输出接收方式
forward函数的输出,根据原始tracing的网络输出,对输出进行类别转换。这个函数在高版本上无法进行列表接收了。
2024-03-12 08:43:50
200
原创 ONNX实践系列-将dbnet.onnx的hardsigmoid op用hardsigmoid.onnx整个去替换掉
这个dbnet.onnx是paddleocr转出来的,自带的有paddle的那个hardsigmoid算子 ,这个不好转到trt等框架,因此我们想把这个hardsigmoid 算子op替换成我们常规的pytorch框架转出来的hardsigmoid onnx那种。
2023-11-24 16:41:20
383
原创 ONNX实践系列-修改yolov5-seg的proto分支输出shape
本文主要介绍要将原始yolov5分割的输出掩膜从[b,c,h,.w]修改为[b, h, w, c]一般的做法就是使用:onnxsim里面带的推断shape的函数过一遍onnxsim就行了!这个是基于yolov5s-seg的,实际其他的m,l等模型那个节点的索引就不是208了。(2)上面我们看到转置完成后,detect的还是没有显式地显示出来。这个以后修改就要相应的去修改!
2023-11-24 16:03:59
675
原创 多线程的重要资料-信号量
(1)https://www.cnblogs.com/ike_li/p/8984186.html(2)C#关于AutoResetEvent的使用介绍 | 康瑞部落(3)AutoResetEvent用法(一)_autoresetevent 的用法-优快云博客(4)c++ - Is there an easy way to implement AutoResetEvent in C++0x? - Stack Overflow (5) c# - What is the C++ equivalent for Au
2023-11-22 09:56:54
241
原创 C++并发与多线程(14) | condition_varible、wait、notify_one、notify_all
当谈到并发编程,特别是在多线程或多进程的上下文中,条件变量(Condition Variables)、等待(wait)、通知一个(notify_one)和通知所有(notify_all)是常见的概念。它们用于协调线程的执行,以实现同步并避免竞争条件。: 条件变量是一种用于阻塞线程直到满足某种条件的同步原语。通常用于协调多个线程的活动。在许多编程语言和库中,条件变量被实现为允许线程等待特定条件满足的对象或结构。等待操作用于线程主动释放锁或互斥锁,并等待某个条件变为真。当线程在条件变量上调用等待。
2023-11-02 18:09:49
713
4
原创 C++并发与多线程(11) | unique_lock Ⅱ
这与一开始的锁定方式不同,因为在某些情况下你可能希望先尝试获取锁,然后在需要的时候再锁定。是C++标准库中的互斥量使用相关工具,它们通常不必直接一起使用,但它们的概念和用途有时会在互斥量的管理中互相关联,具体取决于你的使用情境。所以,unique_lock对象这个mutex的所有权是可以转移(但是不可复制的)。尝试给互斥量加锁,如果拿不到锁,则返回false,如果拿到了锁,返回true,这个函数是不阻塞的。来尝试获取锁,如果无法获取到锁,则不会阻塞,而是立即返回。以下是一个示例C++代码,演示如何使用。
2023-11-01 15:15:52
163
原创 C++并发与多线程(11) | unique_lock Ⅰ
unique_lock也可以带std::adopt_lock标记,含义相同,就是。我们会尝试用mutex的lock()去锁定这个mutex,但如果没有锁定成功,我也会立即返回,并不会阻塞在那里。像lock_guard一样,unique_lock支持很多标记,例如adopt_lock.unique_lock是个类模板,工作中,一般lock_guard(推荐使用);用这个defer_lock的前提是 你不能自己先lock,否则会报异常。这样等待一段时间的时候,另一个线程也在等待这个锁头,就会造成阻塞。
2023-10-30 19:31:28
156
原创 C++并发与多线程(10) | 死锁
只有两个互斥量才会产生死锁问题。举个例子:两个锁——金锁,银锁和两个线程A,B(1)A执行时,这个线程先锁金锁,把金锁Lock()成功了,然后它去lock银锁。出现了上下文切换(2)B执行了,这个线程先锁银锁,因为银锁还没有被锁,所以银锁lock()成功了,B然后就去lock金锁。这个A因为拿不到银锁头,流程走不下去,是不是意思是因为银锁被B锁定了,所以这个A里面去lock银锁的代码运行不下去,被卡着不动!在这个情况下,线程 A 因为无法获得银锁而被阻塞,因为银锁已经被线程 B 锁定了。
2023-10-30 17:01:23
221
转载 C++并发与多线程(9) | 线程安全访问控制
由于两个线程函数是同时的,因此这个时候在线程函数thread2中,由于mutex1已经在线程函数thread1中被锁定了,所以在线程函数thread2中拿不到mutex1的锁头了,因此这个时候是被在。必须保证加锁的顺序是一样的,比如先加的锁后解锁, Lock1 Lock2 Unlock2 Unlock1 ,则其他地方的加锁顺序,必须与这里的顺序一样,这个<<输出运算是全局的,因此也是本身线程不安全的,可以被多个线程访问,因此我们常常发现用cout打印输出,控制台的输出顺序是混乱的。
2023-10-30 10:43:29
341
原创 C++并发与多线程(8) | 互斥量
这就是为什么在多线程编程中,你需要使用同步机制,如互斥量、条件变量等,来确保线程之间的正确协作和共享资源的安全访问,而不是依赖于线程的创建顺序。然而,当涉及多个线程时,线程之间的执行顺序是不确定的,因此在多线程编程中,你需要格外小心,确保多个线程之间的共享资源访问是线程安全的。这意味着线程内的操作通常是原子的,不需要额外的同步措施来保护线程内的数据访问,因为在同一个线程内,不会有其他线程干扰。线程的执行顺序是由操作系统调度的,取决于各种因素,包括处理器的可用性、线程的优先级等。对象超出作用域时自动解锁。
2023-10-25 21:51:44
191
原创 C++并发与多线程(7) | 创建多个线程时数据共享的问题
借助vector存放多个线程thread对象,借助查看运行结果,发现有些乱,因为各个线程是并发执行的,与操作系统内部的运行调度机制有关。主线程也是等待了所有子线程运行结束才结束。
2023-10-25 13:38:37
500
原创 C++并发与多线程(6) | 传递临时对象作为线程参数的一些问题Ⅲ
(1)mutalbe的中文意思是“可变的,易变的”,是constant(即C++中的const)的反义词。在C++中,mutable也是为了突破const的限制而设置的,被mutable修饰的变量将永远处于可变的状态。使用这个函数修饰子线程的临时对象,这样成员变量m_i不用mutable进行修饰,而且myprint2()的输入参数(引用的方式)也不需要const进行修饰了。可以发现m_i值修改的时候,对象的地址实际上是不一样的,即使前面是const修饰的类对象。这里有一个需要注意的地方,就是在子线程中,
2023-10-24 11:40:01
446
原创 c++ 并发与多线程(5)传递临时对象作为线程参数的一些问题Ⅱ
上一篇()提出了传递临时对象作为线程参数的问题,本节借助一个线程ID的概念来更好地理解。
2023-10-23 19:02:53
191
原创 c++ 并发与多线程(12)线程安全的单例模式-2
(1)内部静态变量的懒汉单例是一种线程安全的懒汉单例模式,它利用了C++11的特性,即在局部静态变量(local static variable)上使用线程安全的延迟初始化。(6)在类的成员函数内部声明的静态变量通常用于维护特定于该函数或方法的状态,而不是与整个类相关的状态。(4)内部静态变量来实现懒汉单例模式的优势在于它具有很好的线程安全性,而不需要额外的锁定。(2)请注意,C++11内部静态变量的线程安全性是由C++标准库来保证的,因此无需手动加锁,代码非常简洁和高效。可以看到控制台输出终于正常了!
2023-10-23 15:36:56
683
原创 C++并发与多线程(4) | 传递临时对象作为线程参数的一些问题Ⅰ
(1)若传递int这种简单类型参数,建议都是值传递,不要用引用,避免节外生枝。(2)如果传递类对象,避免隐式类型转换(eg: char *->string)。全部都在创建线程这一行就构建出临时对象(
2023-10-08 22:09:47
302
原创 C++并发与多线程(3) | 其他创建线程的方式
,所以执行完主线程后,ta会被销毁,但是所复制的TA对象依旧存在,因此就不存在对于main中所创建的对象ta,也就不会出现因为ta对象被销毁时,子线程崩溃的问题!即使对象(Ta类的对象ta)被析构了,拷贝得到的对象还是能继续在子线程中运行。这里就是子线程复制的对象(ta的复制对象)先析构,然后主函数里的ta对象在join()之后结束主线程时析构了。所以对于这个问题,只要保证这个类对象中没有引用,没有指针,就不会产生问题了。),所以执行完主线程后,ta会被销毁,但是所复制的TA对象依旧存在。
2023-10-08 19:41:02
142
原创 C++并发与多线程(2) | 线程运行开始和结束的基本方式
当程序运行起来,生成一个进程,该进程所属的主线程开始自动运行。当主线程从main()函数返回,则整个进程执行完毕。主线程从main()开始执行,。,如果主线程执行完毕了,就代表整个进程执行完毕了;此时,一般情况下,。。(这条规律有例外,后续说明)子线程创建的步骤:1)包含头文件thread2)要写初始函数3)在main中写启动这个子线程。运行效果:这个代码是有两个线程在跑的——有两条线同时在走。即使一条线堵住了,另一条还是可以走的。(1)创建了线程,线程执行起点(入口)myprint()
2023-10-07 21:21:11
270
转载 C++并发与多线程(1) | 并发、进程和线程的基本概念
(1)线程是用来执行代码的;(2)把线程理解成一条代码的执行通路,一个新线程代表一条新的通路。(3)一个进程自动包含一个主线程,主线程随着进程默默地启动并运行,我们可以通过编码来创建多个其他线程(非主线程);但是创建的数量最大都不建议超过200-300个,至于到底多少个合适,大家在实际的项目中可以不断调整和优化,有时线程太多的时候效率反而会降低。(4)因为主线程是自动启动的,所以一个进程中最少也是有一个线程(主线程)。(5)多线程程序可以同时做多个事,所以运行效率高。
2023-10-07 12:57:49
132
原创 sam和mobilesam导出onnx的问题
环境:python==3.10,torchvision==0.12.0+cu113 onnx==1.12.0 onnxruntime==1.13.1我们在mobilesam工程(sam工程一样的)导出onnx的时候默认出现:”ValueError: Unsupported ONNX opset version: 16“然后我们就按照一些资料,将opset降低到使用13,结果还是不行:”repeat_interleavefor idx, r_split in enumerate(r_splits):
2023-10-06 10:57:33
1186
原创 In-Place操作及onnx导出
out-of-place只是分配新对象并保留对旧计算图的引用,而in-place操作则需要将所有输入的创建更改为代表此操作的函数。out-of-place只是分配新对象并保留对旧计算图的引用,而 in-place 操作则需要将所有输入的创建更改为代表此操作的函数。这就是为什么我建议使用 PyTorch 标准的in-place 操作(如上面的in-place ReLU) ,而不是手动实现。就地操作:是直接更改给定Tensor的内容而不进行复制的操作,即不会为变量分配新的内存(不分配新的对象)。
2023-09-19 20:44:44
358
原创 Halcon学习之一维测量实战之测量矩形(一)
大家还记不记得,我们之前文章中介绍的芯片那个,芯片那个就是每次旋转都用模板匹配找到它,然后测量矩形跟着它转,然后来做测量。我们后面还会涉及到拟合的问题,这个地方测量是测量直线、弧形这种距离。后面我们涉及到求角度,点到直线的距离,点到弧线的距离,这就会涉及到拟合。然后我们可以看到上面的代码,仍然是形成测量矩形,2个测量矩形,两次测量,然后关闭两个测量句柄!测量充电器的引脚,然后每次旋转充电器,让测量矩形都跟着它转,这就是定位+测量,我们要测量这个钥匙的尺寸,就是要当我们的相机垂直我们的待测物体钥匙的时候。
2023-08-02 00:05:08
886
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人