代码调试工具gdb是一个能够让我们在工作中高效排查代码异常根源的利器。
在此将gdb针对多线程的调试方式做一个笔记,也方便后续回顾以及分享大家。
本文采用的是一个简单的多线程代码示例,同时调试是在mac上进行的
mac安装gdb brew install gdb
即可
开始之前先简单介绍几个gdb调试多线程的子命令
目标:在不加锁的情况下,多个线程的运行交叉运行的,导致进程内部共享的变量对外的体现不是连续的。
代码如下
#include
#include
#include using namespace std;static int g_a = 0;void pthread_func1() { for (int i = 1;i < 5000; ++i) { g_a ++;}
}void pthread_func2() { for (int i = 5000;i < 10000; ++i) { g_a ++;}
}int main() { thread t1(pthread_func1);thread t2(pthread_func2);t1.join();t2.join();return 0;
}
编译:
g++ -std=c++11 -g pthread_test.cc -o pthread_test -pthread
调试过程如下:
通过以上调试我们可以发现在当前进程中的变量g_a每运行一次并不是累加1,可能会累加2,而且代码的跳转也能发现其实是多个线程交替执行。
基本的调试方式也就是使用我们已经说过的线程相关调试命令了。
目标:在加锁的情况下,我们的进程全局变量的访问变成了串行方式
测试代码如下:
#include
#include
#include using namespace std;mutex g_lock;
static int g_a = 0;void pthread_func1() { for (int i = 1;i < 5000; ++i) { g_lock.lock();g_a ++;g_lock.unlock();}
}void pthread_func2() { for (int i = 5000;i < 10000; ++i) { g_lock.lock();g_a ++;g_lock.unlock();}
}int main() { thread t1(pthread_func1);thread t2(pthread_func2);t1.join();t2.join();return 0;
}
编译调试过程如下:
此时可以看到我们加了mutex的锁之后对于整个进程来说,执行一次变量只会加一,显然满足了全局变量状态变化的逻辑
源代码以及运行过程中各个线程的子变量信息实时显示,且通过断点 我们清楚得看到了代码运行过程中的跳转逻辑,可以说解决问题的效率事半功倍了。
多线程有什么好处?提高CPU的利用率,更好地利用系统资源,使用Monitor类可以同步静态/实例化的方法的全部代码或者部分代码段,使用不同的同步类创建自己的同步机制。多线程指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程提升整体处理性能。多线程是指程序中包含多个执行流,即...
Step1:在界面主函数的构造函数中初始化多线程 auto mythread = new QThread(); //新建connect(mythread , &QThread::finished, mythread, &QObject::deleteLater);//线程运行结束后释放内存object1->moveToThread...
一、thread的基本用法
参见C++使用thread类多线程编程 。
二、类外使用多线程,访问类的成员
这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数。
#include
本博文是根据中科大信息学院谭立湘老师的课件加上自己的理解整理出来的 ************************************************************************************ NVIDIA在2007年推出CUDA这个统一计算架构 CUDA的基本思想是支持大量的线程级并...
一、parallel communication patterns 并行通信模式 Map:映射,在特定的位置读取和写入。 Gather:收集,从多个不同的位置读入,写入一个位置。 Scatter:分发,写入多个位置。 Transpose转置 结构数组缩写为AOS,数组结构缩写为SOA 转置运算是指任务重新排序内存中的数...