判断是否在同一个线程-GetCurrentThreadId()用法
线程
在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。利用线程,用户可按下一个按钮,然后程序会立即作出响应,而不是让用户等待程序完成了当前任务以后才开始响应。
判断是否在同一个线程中的根本方法也比较简单,在Windows上直接用 GetCurrentThreadId() 比较;
GetCurrentThreadId() 会直接输出线程id。
注意:
1.线程id是动态分配的,因此如果某一个线程结束以后,这个id号还可能会分配给另一个线程,所以会有重复。
2.之所以会出现相同ID的情况,可能是以下原因:先前的线程已经被销毁了;采用的是异步机制;消息机制;线程运行得太短时间了,还没有等其它线程启动就已经运行完了。
3.直接输出了GetCurrentThreadID的返回值可能会出现重复的现象,
这个返回值不能直接输出的,该函数采用的是寄存器返回,很快会被其他操作覆盖!
正确的做法是:
将GetCurrentThreadID的返回值赋值给一个临时变量;而后输出该临时变量
以前自己将GetCurrentThreadID的值作为map的key,也出了问题,改用临时变量就解决了。
4.打印出id的那句是:
TRACE("Current Thread ID = 0x%X\n", AfxGetThread()->m_nThreadID);
直接输出也可以。
一、关于设置断点和单步执行
很多同学非常依赖于调试器的断点功能和单步功能。这在单线程情况下倒还好(不过有些单线程但涉及GUI的程序,也会有点麻烦)。至于多线程程序的调试,这两种手段简直就是噩梦的开始。多线程造成的主要问题大都和竞态条件(Race Condition,详细解释看“这里 ”)有关。
而设置断点或单步跟踪可能会严重干扰 多线程之间的竞争状态。导致你看到的是一个假象。比如本来有两个线程并发执行,存在某些不和谐的Bug(由竞态引起)。一旦你在某一个线程设置了断点,该线程在断点处停住了,只剩下另一个线程在跑。这时候,并发的场景已经完全被破坏了,你通过调试器看到的可能 是一个和谐的场景。
稍微跑一下题。这很类似量子力学的“测不准原理”,观测者的观测行为干扰了被测量的客体,导致观测者看到的是一个干扰后的现象。
二、关于Log输出
既然断点和单步不好用。那咋办捏?一个替代方案是输出log日志。它可以有效减轻断点和单步所导致的(针对竞态条件的)副作用。
1、传统Log机制的问题
传统的log输出主要是打印到屏幕或者输出到文件。对于C++而言,标准库内置的类和函数(比如cout、printf、fputs)可能会有线程安全的问题(和编译器的具体实现有关)。尤其是标准流类库(iostream)的八个全局对象,更是要小心慎用。轻则输出的log文本混杂,重则导致程序崩溃。
鉴于上述原因,应该尽量使用第三方线程库内置的log机制来搞定log输出功能。比如ACE内置的ACE_Log_Msg等。
2、Log函数要短小精悍
很多情况下,我们会包装一个公用的函数来实现log输出功能。然后在该函数内部调用线程库的log类/函数。为了不影响线程的竞态条件,这个log函数要尽可能简单轻便:不要涉及太多杂七杂八的琐事、千万别进行耗时的操作、尽量不操作一些全局的变量。
3、Log的副作用
不过捏,即使log函数再短小精悍,也还是有可能影响竞态条件(毕竟log也有开销,也要消耗CPU时间)。
万一竞态条件受到log的影响,那就比较棘手了。我以前就碰到过这种情况:加了log,程序没有问题;去掉log,程序随机崩溃。这种情况一般有两种可能:要么是log功能本身有问题,要么是程序的竞态条件非常敏感(连log的开销都会有影响)。
这时候你能依靠的就只有肉眼和人脑了。先把相关的代码和文档仔细看上几遍(最好再找其他有经验的人一起Code Review),然后大家一起开动脑筋使劲琢磨。
三、关于Debug版本和Release版本
C++程序经常有Debug版本和Release版本的区别。有些时候,这也会导致一些多线程的问题。
由于Debug版本包含了一些调试信息、启用了某些调试机制(比如assert宏)。所以就可能 影响到多线程的竞争状态。在倒霉的时候,会碰上Debug版本工作正常,Release版本程序随机崩溃。要避免这种情况,可以考虑下面两个办法:
1、放弃使用Debug版本
你可以干脆放弃使用Debug版本。在这种情况下,你需要考虑把诸如assert之类调试相关的宏替换成自己的一套宏,使得在非Debug版本下也可以生效。
2、两种版本同步测试
使用此方法,程序员平时自测可以使用Debug版本,但是测试人员日常测试的必须是Release版本。具体的操作步骤可以利用每日构建来辅助进行(每日构建的介绍参见“这里 ”)。一定要避免:在平时仅仅搞Debug版本的测试,等到发布前夕再制作Release版本。这种做法是非常危险的!
判断是否在同一个线程-GetCurrentThreadId()用法的更多相关文章
- 解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good
概述查看Qt源码可知,Q_INVOKABLE是个空宏,目的在于让moc识别. 使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起. Q_INVOKABLE与QMe ...
- java中判断list是否为空的用法
1.如果想判断list是否为空,可以这么判断: if(null == list || list.size() ==0 ){ //为空的情况 }else{ //不为空的情况 } 2.list.isEmp ...
- 四种Java线程池用法解析
本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...
- Java集合的线程安全用法
线程安全的集合包含2个问题 1.多线程并发修改一 个 集合 怎么办? 2.如果迭代的过程中 集合 被修改了怎么办? a.一个线程在迭代,另一个线程在修改 b.在同一个线程内用同一个迭代器对象进行迭代. ...
- 如何判断C#的Finalizer线程有没有被阻塞
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何判断C#的Finalizer线程有没有被阻塞.
- C#线程池用法
C#线程池用法 在C#编程语言中,使用线程池可以并行地处理工作,当强制线程和更新进度条时,会使用内建架构的ThreadPool类,为批处理使用多核结构,这里我们来看在C#编程语言中一些关于来自Syst ...
- c/c++ 多线程 多个线程等待同一个线程的一次性事件
多线程 多个线程等待一个线程的一次性事件 背景:从多个线程访问同一个std::future,也就是多个线程都在等待同一个线程的结果,这时怎么处理. 办法:由于std::future只能被调用一次get ...
- 如何判断是否为同一个App,Ionic3如何修改包名
如何判断是否同一个App 使用Ionic3创建了两个项目demo1.demo2,然后使用同一个JDK,生成了两个不同的keystore证书. 结果在手机端安装的时候,先安装demo1,没有任何替换的提 ...
- 同一个线程多次调用start()会出现的问题
结果: 线程首先会运行一次,然后抛出java.lang.IllegalThreadStateException异常. 根据控制台的异常信息,定位到Thread.java的第708行,也就start() ...
随机推荐
- AlphaGo设计师黄士杰:“最强的学习技能在人类的脑袋里”
AlphaGo设计师黄士杰:“最强的学习技能在人类的脑袋里” 深度学习和强化学习结合看来才能解决彩票预测的问题 可以这么说,AlphaGo的成功就是深度学习与强化学习的胜利,因为两者结合在一起,建构判 ...
- netperf 网络性能测试
Netperf是一种网络性能的测量工具,主要针对基于TCP或UDP的传输.Netperf根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求 ...
- Android4.0 主线程不能访问网络异常解决办法
从两个方面说下这个问题: 1. 不让访问网络的原因 2. 解决该问题的办法 不让访问网络的原因: 由于对于网络状况的不可预见性,很有可能在网络访问的时候造成阻塞,那么这样一来我们的主线程UI线程 就会 ...
- Java中this和super关键字
今天练习到Java中的this和super关键字,我有如下总结: 1.子类继承父类,子类初始化对象,必须先调用父类构造方法,因为随时有可能要使用父类的成员变量. 2.get和set方法只是对成员变量进 ...
- to refactor for refactor
v1.1 if all algorithm are in one function, it will expand. so each operate type should be separated. ...
- Python调用大漠插件
Python版本要用32位的?我去官网下载,太慢了,就在腾讯软件里面下载了一个,结果实验成功 import win32com.client dm = win32com.client.Dispatch( ...
- Web安全学习笔记之更新kali国内源
vi /etc/apt/sources.list #中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib ...
- P4577 [FJOI2018]领导集团问题
P4577 [FJOI2018]领导集团问题 我们对整棵树进行dfs遍历,并用一个multiset维护对于每个点,它的子树可取的最大点集. 我们遍历到点$u$时: 不选点$u$,显然答案就为它的所有子 ...
- Quick Find (QF)
Quick Find 顾名思义就是快速查找,构建一个数组,通过下标即可迅速查找其id Union and Find:构建一个数组,下标为索引,数组元素的值为其id,初始id和索引相同 Union(p, ...
- opencv学习之路(4)、Mat类介绍,基本绘图函数
一.Mat类创建 Mat img;//创建无初始化矩阵 Mat img1(,,CV_8UC1);//200行,100列(长200,宽100) Mat img2(Size(,),CV_8UC3,Scal ...