1.線程的查看
首先創建兩個線程
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
void* pthread_run1(void* arg)
{
(void)arg;
while(1)
{
cout << "I am thread1,ID" << pthread_self() << endl;
sleep(1);
}
}
void* pthread_run2(void* arg)
{
(void)arg;
while(1)
{
cout << "I am thread2 ID:" << pthread_self() << endl;
sleep(1);
}
}
int main()
{
pthread_t tid1;
pthread_t tid2;
pthread_create(&tid1,NULL,pthread_run1,NULL);
pthread_create(&tid2,NULL,pthread_run2,NULL);
cout << "I am main thread" << endl;
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
分析:在上面的程序中創建了兩個線程,程序執行起來,main函數所在的程序爲主線程,在這個主線程中有兩個新的線程運行
命令行查看:
//查看但錢運行的進程
ps -aux | grep 執行文件
//查看當前運行的輕量級進程
ps -aL | grep 執行文件
//查看主線程和新線程的關係
pstree -p 主線程ID
2.線程棧結構的查看
1.獲取線程ID
2.通過命令查看棧結構 pstack 線程ID
3.利用gdb查看線程信息
1.將進程附加到gdb調試器當中,查看是否創建了新線程:gdb attach 主線程ID
2.查看線程的一些信息
//1.查看進程:info inferiors
//2.查看線程:info threads
//3.查看線程棧結構:bt
//4.切換線程:thread n(n代表第幾個線程)
4.利用gdb調試多線程
當程序沒有啓動,線程還沒有執行,此時利用gdb調試多程序和調試普通程序一樣,通過設置斷點,運行,查看信息等等,在這裏不演示了,最後會加上調試線程的命令
1.設置斷點:
//1.設置斷點:break 行號/函數名
//2.查看斷點:info b
2.執行線程2的函數,執行完畢繼續運行到斷點處
1.繼續使某一線程運行:thread apply 1-n(第幾個線程)n
2.重新啓動陳故鄉運行到斷點處:r
3.只運行當前線程
1.設置:set scheduler-locking on
2.運行:n
4.所有線程併發執行:
1.設置:set scheduler-locking off
2.運行:n
**總結:**調試多線程的命令
命令 | 用法 |
---|---|
info threads | 顯示當前可調試的所有線程,每個線程有一個GDB爲其分配的ID,後面操作線程的時候會用到這個ID 。前面的有*的是當前調試的線程 |
thread ID | 切換但錢的線程爲指定ID的線程 |
break thread_test.c:123 thread all(例:在相應函數的位置設置斷點break pthread_run1) | 在所有線程中相應的行上設置斷點 |
thread apply ID1 ID2 command | 讓一個或者多個線程執行GDB命令command |
thread apply all command | 讓所有被調試線程執行GDB命令command |
set scheduler-locking 選項 command | 設置線程是以什麼方式來執行命令 |
set scheduler-locking off | 不鎖定任何線程,也就是所有線程都執行,這是默認值 |
set scheduler-locking on | 只有當前被調試程序會執行 |
set scheduler-locking on step | 在單步的時候,除了next過一個函數的情況(熟悉情況的人都知道,這其實是一個設置斷點然後continue的行爲)以外,只有當前線程會執行 |