多线程调试 Linux:技巧大全
在软件开发中,多线程编程已经成为了非常普遍的技术。然而,多线程编程也带来了许多调试难题,因为多个线程之间的交互以及竞争会导致程序出现意料之外的结果。为了解决这些问题,你需要掌握一些多线程调试的技巧。
本文将为你介绍一些常见的多线程调试技巧,来帮助你定位和解决多线程编程中的问题。
1. 使用调试器
使用调试器来调试多线程程序是最常见的方法。调试器可以让你检查程序中的每个线程,包括它们的堆栈、变量、程序计数器等。你可以在需要的时候停止或继续任何一个或多个线程,并检查它们在不同时刻的状态。
在 Linux 中,你可以使用 GDB 或 CLion 等调试器来进行多线程调试。下面是一些使用 GDB 调试多线程程序的技巧:
– 使用 command 命令创建自定义命令。你可以使用 GDB 的 command 命令来创建自定义命令,这些命令可以用来检查线程之间的状态、设置断点等操作。
– 设置断点。在多线程程序中,你需要在正确的时机设置断点,并检查每个线程在达到断点时的状态。
– 使用线程列表命令。GDB 的 info threads 命令可以列出所有正在运行的线程,你可以使用该命令来检查每个线程的状态和堆栈信息。
2. 使用 log
如果你的程序中存在未捕获的异常或信号,你可以在程序中记录日志以便后续分析。在多线程编程中,使用 log 来记录每个线程的状态和行为是非常有用的。你可以使用 log 来记录以下信息:
– 队列和缓冲区的状态
– 每个线程的输入和输出
– 每个线程的堆栈
你可以使用 syslog 或者其他日志框架来记录日志。如果你想对每个线程单独记录日志,你可以使用线程特定的标识符来记录日志。
3. 使用静态分析工具
静态分析工具可以帮助你找到程序中的潜在错误。在多线程程序中,你可以使用静态分析工具来找到以下问题:
– 数据竞争:多个线程同时访问共享资源,导致写入冲突
– 死锁:多个线程同时等待同一个锁,导致无法继续执行
– 值域错误:变量的值不在其有效范围内,可能导致内存错误或者安全问题
在 Linux 中,你可以使用 Clang 或者 Valgrind 等静态分析工具来进行多线程程序分析。
4. 使用多线程可视化工具
多线程可视化工具可以帮助你更好地理解程序的执行流程。这些工具通常会将每个线程表示为一个颜色编码的线条或者图标,并提供一个时间轴来显示每个线程的执行时间以及线程之间的交互。
在 Linux 中,你可以使用 PARSEC 或者 Camcops 等多线程可视化工具来进行多线程程序分析。
5. 编写可重现的测试用例
在找出多线程程序中的问题时,编写可重现的测试用例是非常重要的。一个可重现的测试用例可以让你轻松地重现程序中的问题,并找到导致程序异常的原因。
在编写测试用例时,你需要注意以下几点:
– 在程序中使用固定的随机种子以确保测试的可重现性
– 尝试模拟不同的并况,包括竞争和互斥访问
– 检查每个线程的状态,并确保线程之间的互斥访问正确实现
结论
在多线程编程中,调试是一个非常复杂的过程,需要你掌握大量的技巧。本文介绍了一些常见的多线程调试技巧,包括使用调试器、使用 log、使用静态分析工具、使用多线程可视化工具以及编写可重现的测试用例。
使用这些技巧可以帮助你定位和解决程序中的问题,提高程序的稳定性和可靠性。同时,也可以增加你在多线程编程方面的经验和技能。
相关问题拓展阅读:
- 【求助】linux下的C语言多线程,怎样监视键盘上的输入?
- linux内核如何打开超线程
- linux手册翻译——pthread_setname_np()
【求助】linux下的C语言多线程,怎样监视键盘上的输入?
发所用语言为C..
一般的..要想学好嵌入式开发..就要两个都会..
如果只学linux,这个只是为以后从事linux服务器搭建,管理和维护等..差不多就是跟硬件打交道..
而嵌入式开发就相当于..在windows下用C,C++,C#,java等开发一样..只不过他的开发平台换成了linux…
如果想自学建议按照以下步骤:
学习步骤如下:
1、Linux 基础
安装Linux操作系统
Linux文件系统
Linux常用命令
Linux启动过程详解
熟悉Linux服务能够独立安装Linux操作系培悔陪统
能够熟练使用Linux系统的基本命令
认识Linux系统的常用服务安装Linux操作系统
Linux基本命令实践
设置Linux环境变量
定制Linux的服务 Shell 编程基础使用vi编辑文件
使用Emacs编辑文件
使用其他编辑器
2、Shell 编程基础
Shell简介
认识后台程序
Bash编程熟悉Linux系统下的编辑环境
熟悉Linux下的各种Shell
熟练进行shell编程熟悉vi基本操作
熟悉Emacs的基本操作
比较不同shell的区别
编写一个测试服务器是否连通的shell脚本程序
编写一个查看进程是否存在的shell脚本程序
编写一个带有循环语句的shell脚本程序
3、Linux 下的 C 编程基础
linux C语言环境概述
Gcc使用方法
Gdb调试技术
Autoconf
Automake
Makefile
代码优化 熟悉Linux系统下的开发环境
熟悉Gcc编译器
熟悉Makefile规则编写Hello,World程序
使用 make命令编译程序
编写带有一个循环的程序
调试一个有问题的程序
4、嵌入式系统开发基础
嵌入式系统概述
交叉编译
配置TFTP服务
配置NFS服务
下载Bootloader和内核
嵌入式Linux应用软件开发流程
熟悉嵌入式系统概念以及开发流程
建立嵌入式系统开发环境制作cross_gcc工具链
编译并下载U-boot
编译并下载Linux内核
编译并下载Linux应用程序
嵌入式系统移植
Linux内核代码
平配蠢台相关代码分析
ARM平台介绍
平台移植的关键技术
移植Linux内核到 ARM平台 了解移植的概念
能够移植Linux内核移植Linux2.6内核到 ARM9开发板
5、嵌入式 Linux 下串口通信
串行I/O的基本概念
嵌入式Linux应用软件开发流程
Linux系统的文件和设备
与文件相关的系统调用
配置超级终端和MiniCOM 能够熟悉进行串口通信
熟悉文件I/O 编写串口通信程序
编写多串口通信程序
6、嵌入式系统中多进程程序设计
Linux系统进程概述
嵌入式系统的进程特点
进程操作
守护进程
相关的系统调用了解Linux系统中进程的概念
能够编写多进程程序编写多进程程序
编写一个守护进程程序
sleep系统调用任务管理、同步与通信 Linux任务概述
任务调度
管道
信号
共享内存
任务管理 API 了解Linux系统任务管理机制
熟悉进程间通信的几种方式
熟悉嵌入式Linux中的任务间同步与通信
编写一个简单的管道程序实现文件传输
编写前薯一个使用共享内存的程序
7、嵌入式系统中多线程程序设计
线程的基础知识
多线程编程方法
线程应用中的同步问题了解线程的概念
能够编写简单的多线程程序编写一个多线程程序
8、嵌入式 Linux 网络编程
网络基础知识
嵌入式Linux中TCP/IP网络结构
socket 编程
常用 API函数
分析Ping命令的实现
基本UDP套接口编程
许可证管理
PPP协议
GPRS 了解嵌入式Linux网络体系结构
能够进行嵌入式Linux环境下的socket 编程
熟悉UDP协议、PPP协议
熟悉GPRS 使用socket 编写代理服务器
使用socket 编写路由器
编写许可证服务器
指出TCP和UDP的优缺点
编写一个web服务器
编写一个运行在 ARM平台的网络播放器
9、GUI 程序开发
GUI基础
嵌入式系统GUI类型
编译QT
进行QT开发熟悉嵌入式系统常用的GUI
能够进行QT编程使用QT编写“Hello,World”程序
调试一个加入信号/槽的实例
通过重载QWidget 类方法处理事件
10、Linux 字符设备驱动程序
设备驱动程序基础知识
Linux系统的模块
字符设备驱动分析
fs_operation结构
加载驱动程序了解设备驱动程序的概念
了解Linux字符设备驱动程序结构
能够编写字符设备驱动程序编写Skull驱动
编写键盘驱动
编写I/O驱动
分析一个看门狗驱动程序
对比Linux2.6内核与2.4内核中字符设备驱动的不同
Linux 块设备驱动程序块设备驱动程序工作原理
典型的块设备驱动程序分析
块设备的读写请求队列了解Linux块设备驱动程序结构
能够编写简单的块设备驱动程序比较字符设备与块设备的异同
编写MMC卡驱动程序
分析一个文件系统
对比Linux2.6内核与2.4内核中块设备驱动的不同
11、文件系统
虚拟文件系统
文件系统的建立
ramfs内存文件系统
proc文件系统
devfs 文件系统
MTD技术简介
MTD块设备初始化
MTD块设备的读写操作了解Linux系统的文件系统
了解嵌入式Linux的文件系统
了解MTD技术
能够编写简单的文件系统为 ARM9开发板添加 MTD支持
移植JFFS2文件系统
通过proc文件系统修改操作系统参数
分析romfs 文件系统源代码
创建一个cramfs 文件系统
望采纳:可是一个字一个字钱敲出来的..
另外,站长团上有产品团购,便宜有保证
在袜冲Microsoft Windows 中,键盘和鼠标是两个标准的用户输入源,在一些交叠的操作中通常相互补充使用。当然,鼠标在今天的应用程序中比10年前使用得更为广泛。甚至在一些应用程序中,我们更习惯于使用鼠标,例如在游戏、画图程序、音乐程序,以及Web创览器等程序中就是这样。然而,我们可以不使用鼠标,但绝对不能从一般的PC中拆掉键盘。
Windows程序获得键盘输入的方式:键盘输入以消息的形式传递给程序的窗口过程。实际上,之一次学习消息时,键盘就是一个明显的例子:消息应该传递给应用程序的信息类型。
Windows用8种不同的消息来传递不同的键盘事件。这好像太多了,但是(如野就像我们所看到的一样)程序可以忽略其中至少一半的消息而不会有任何问题。并且,在大多数情况下,这些消息中包含的键盘信息会多于程序所需要的。处理键盘的部分工作就是识别出哪些消息是重要的,哪些是不重要的。
键盘基础知识
虽然应用程序在很多情况下可以通过鼠标实现信息的输入,但到现在为止键盘仍然是PC机中不可替代的重要输入设备。
用键盘当作输入设备,每当用户按下或释放某一个键时,会产生一个中断,该中断激活键盘驱动程序KEYBOARD.DRV来对键盘中断进行处理。 KEYBOARD.DRV程序会根据用户的不同操作进行编码,然后调用Windows用户模块USER.EXE生成键盘消息,并将该消息发送到消息队列中等候处理。
1.扫描码和虚拟码
扫描码对应着键盘上的不同键,每一个键被按下或释放时,都会产生一个唯一的扫描码作为本身的标识。扫描码依赖于具体的硬告橡歼件设备,即当相同的键被按下或释放时,在不同的机器上可能产生不同的扫描码。在程序中通常使用由Windows系统定义的与具体设备无关的虚拟码。在击键产生扫描码的同时,键盘驱动程序KEYBOARD.DRV截取键的扫描码,然后将其翻译成对应的虚拟码,再将扫描码和虚拟码一齐编码形成键盘消息。所以,最后发送到消息队列的键盘消息中,既包含了扫描码又包含了虚拟码。
经常使用的虚拟码在WINDOWS.H文件中定义,常用虚拟码的数值、常量符号和含义如表所示。
取值(16进制) 常量符号 含义
VK_LBUTTON 鼠标左键
VK_RBUTTON 鼠标右键
VK_CANCEL Break中断键
VK_MBUTTON 鼠标中键
未定义
VK_BACK (BackSpace)键
VK_TAB Tab键
0A-0B — 未定义
0C VK_CLEAR Clear键
0D VK_RETURN Enter键
0E-0F — 未定义
VK_SHIFT Shift键
VK_CONTROL Ctrl键
VK_MENU Alt键
VK_PAUSE Pause键
VK_CAPTIAL CapsLock键
汉字系统保留
1A — 未定义
1B VK_ESCAPE Esc键
1C-1F — 汉字系统保留
VK_SPACE 空格键
VK_PRIOR PageUp键
VK_NEXT PageDown键
VK_END End键
VK_HOME Home键
VK_LEFT ←(Left Arrow)键
VK_UP ↑(Up Arrow)键
VK_RIGHT →(Right Arrow)键
VK_DOWN ↓(Down Arrow)键
VK_SELECT Select键
2A — OEM保留
2B VK_EXECUTE Execute键
2C VK_SNAPSHOT Print Screen键
2D VK_INSERT Insert键
2E VK_DELETE Delete键
2F VK_HELP Help键
VK_0-VK_9 数字键0-9
3A未定义
A VK_A-VK_Z 字母键A-Z
5B-5F — 未定义
VK_NUMPAD0-VK_NUMPAD9 小键盘数字键0-9
6A VK_MULTIP *(乘号)键
6B VK_ADD +(加号)键
6C VK_SEPAPATOR 分隔符键
6E VK_SURACT -(减号)键
6F VK_DECIMAL .(小数点)键
VK_DIVIDE /(除号)键
F VK_F1-VK_F24 F1-F24功能键
VK_NUMBERLOCK Number lock键
VK_SCROLL Scroll lock键
B9 — 未定义
BA-C0 — OEM保留
C1-DA — 未定义
DB_E4 — OEM保留
E5 — 未定义
E6 — OEM保留
E7-E8 — 未定义
E9-F5 — OEM保留
F6-FE — 未定义
2.输入焦点
同一时刻,Windows中可能有多个不同的程序在运行,也就是说有多个窗口同时存在。这时,键盘由多个窗口共享,但只有一个窗口能够接收到键盘消息,这个能够接收键盘消息的窗口被称为拥有输入焦点的窗口。
拥有输入焦点的窗口应该是当前的活动窗口,或者是活动窗口的子窗口,其标题和边框会以高亮度显示,以区别于其他窗口。拥有输入焦点的也可以是图标而不是窗口,此时,Windows也将消息发送给图标,只是消息的格式略有不同。
窗口过程可以通过发送WM_SETFOCUS和 WM_KILLFOCUS消息使窗体获得或失去输入焦点。程序也可以通过捕获WM_SETFOCUS和WM_KILLFOCUS消息来判断窗体何时获得或失去输入焦点。其中WM_SETFOCUS消息表示窗口正获得输入焦点,WM_ KILLFOCUS消息表示窗口正失去输入焦点。
3.键盘消息
键盘消息分为系统键消息和非系统键消息。系统键消息是指由Aft键和其他键组合而产生的按键消息。当系统键被按下时产生WM_ SYSKEYDOWN消息,当系统键被释放时产生WM_SYSKEYUP消息。 Aft键与其他键形成的组合键通常用于对程序菜单和系统菜单进行选择,或用于在不同的程序之间进行切换。因此,系统键消息应该交由Windows进行处理,用户所编制的程序一般不处理系统键消息,而是将这些消息交由DefWindowProc函数进行处理。如果用户想对系统键消息进行处理,应该在处理完这些消息后,再将其发送给DefWindowProc函数,使得Windows系统能够正常工作。
某些击键消息可以被转换成字符消息,例如字母键、数字键等。而有些键只能产生按键消息而没有字符消息,例如 Shift键、Insert键等。消息循环中的 TranslateMessage函数可以实现从击键消息向字符消息的转化。当GetMessage函数捕获一个WM_SYSKEYDOWN消息或 WM_KEYDOWN消息后,TranslateMessage函数判断产生该消息的键是否能够被转换成字符消息,如果能,就将该消息转换成字符消息,再通过DispatchMessape函数将转换后的字符消息发送到消息队列中去。字符消息共有以下四种,如表所示。
字符 系统字符 非系统字符
普通字符 WM_SYSCHAR WM_CHAR
死字符 WM_SYSDEADCHAR WM_DEADCHAR
其中死字符是由某些特殊键盘上的按键所造成的,Windows一般忽略死字符所产生的消息。
Windows的消息一般是通过一个MSG结构体变量传送给消息处理函数的。对于键盘消息, MSG结构体变量的各个域中较重要的是lParam域和 wParam域。wParam域用于保存按键的虚拟键代码或字符的ASCII码。对于非字符消息,wParam域保存按键的虚拟健代码;对于字符消息, wParam域不保存字符的ASCII码。lParam域则用于保存击键时产生的附加信息,实际上一个32位的lParam变量被分为六部分,记录了以下相关信息:重复次数、OEM扫描码、扩展键标志、关联键标志、前一击键状态和转换状态。lParam域各位的含义如表所示。
位数 含义
击键重复次数累加
OEM扫描码
是否为扩展键
未定义
是否便用关联键,及Alt键是否同时按下。
前一次击键状态,0表示该键前一次状态为抬起,1表示前一次状态为按下
转换状态
按键的次序不同,产生的消息也不相同。例如,按下并释放1键,读过程依次产生如表所示三条消息。按下1键所产生的消息和wParam的取值
消息 wParam变量取值
WM_KEYDOWN 虚拟码1
WM_CHAR ASCII码“1”
WM_KEYUP 虚拟码1
如果按下Shift键后再按下1键并释放,则依次产生如表所示的消息。按下 Shift键后按 1健所产生的消息和 wParam的取值
消息 wParam变量取值
WM_KEYDOWN 虚拟码 VK_SHIFT
WM_KEYDOWN 虚拟码 VK_1
WM_CHAR ASCII码 “1”
WM_KEYUP 虚拟码 VK_1
WM_KEYUP 虚拟码 VK_SHIF
键盘应用实例
下面通过一个应用程序实例来说明在实际编程中如何处理键盘消息。
#include
#include
// 全局变量
RECT rc; //记录滚屏的矩形区域
?
int xChar, yChar; //文本输入点坐标
WNDCLASSEX wnd; //窗口类结构变量
char szAppName = “键盘消息监视程序”; //窗口类名
//函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance,int iCmdShow);
//函数:WinMain
//作用:入口函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
MSG msg;
if(!MyRegisterClass(hInstance))
{
return FALSE;
}
if(!InitInstance(hInstance,iCmdShow))
{
return FALSE;
}
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
//函数:ShowKey
//作用:实现在窗口中显示按键信息
void ShowKey (HWND hwnd, int iType,char *szMessage,WPARAM wParam,LPARAM lParam)
{
static char *szFormat ={“%-14s %3d %c %6u %4d %5s %5s %6s %6s”,
”%-14s %3d %c %6u %4d %5s %5s %6s %6s” };
char szBuffer;
HDC hdc;
ScrollWindowEx(hwnd, 0, -yChar, &rc,&rc,NULL,NULL,SW_INVALIDATE);
hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
TextOut (hdc,
xChar,
rc.bottom – yChar,
szBuffer,
wsprintf szBuffer,
szFormat,
szMessage, //消息
wParam, //虚拟键代码
(BYTE) (iType ? wParam :‘ ’),//显示字符值
LOWORD (lParam), // 重复次数
HIWORD (lParam) & 0xFF, // OEM键盘扫描码
//判断是否为增强键盘的扩展键
(PSTR) (0x& lParam ? “是” : “否”),
//判断是否同时使用了ALT键
(PSTR) (0x& lParam ? “是” : “否”),
(PSTR) (0x& lParam ? “按下” : “抬”),
//判断前一次击键状
(PSTR)(0x& lParam ? “按下” : “抬起”))
//判断转换状态?
);
ReleaseDC (hwnd, hdc); ?
ValidateRect (hwnd, NULL); ?
}
//函数:WndProc
//作用:处理主窗口的消息
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static char szTop =”消息键 字符 重复数 扫描码 扩展码 ALT 前一状态 转换状态”;
static char szUnd =”_______ __ ____ _____ ______ ______ ___ _______ ______”;
//在窗口中输出文字作为信息标题
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
switch (iMsg)
{
case
hdc = GetDC (hwnd); //设定字体
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)); //检取当前字体的度量数据
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;//保存字体平均宽度
yChar = tm.tmHeight; //保存字体高度
ReleaseDC (hwnd, hdc);
rc.top = 3 * yChar / 2;
return 0;
case
//窗体改变后保存新的滚屏区域右下角坐标
rc.right = LOWORD (lParam);
rc.bottom = HIWORD (lParam);
UpdateWindow (hwnd);
return 0;
case WM_PAINT: //处理窗口重绘消息
InvalidateRect (hwnd, NULL, TRUE);
hdc = BeginPaint (hwnd, &ps);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
SetBkMode (hdc, TRANSPARENT) ;
TextOut (hdc, xChar, yChar / 2, szTop, (sizeof szTop) – 1) ;
TextOut (hdc, xChar, yChar / 2, szUnd, (sizeof szUnd) – 1) ;
EndPaint (hwnd, &ps);
return 0;
case WM_KEYDOWN:
//处理键盘上某一键按下的消息
ShowKey (hwnd, 0, “WM_KEYDOWN”,wParam, lParam);
return 0;
case WM_KEYUP:
//处理键盘上某一按下键被释放的消息
ShowKey (hwnd, 0, “WM_KEYUP”, wParam, lParam);
return 0;
case WM_CHAR:
//处理击键过程中产生的非系统键的可见字符消息
howKey (hwnd, 1, “WM_CHAR”, wParam, lParam);
return 0;
case WM_DEADCHAR:
//处理击键过程中产生的非系统键”死字符”消息
ShowKey (hwnd, 1, “WM_DEADCHAR”, wParam, lParam);
return 0;
case WM_SYSKEYDOWN:
//处理系统键按下的消息
ShowKey (hwnd, 0, “WM_SYSKEYDOWN”,wParam, lParam);
break;
case WM_SYSKEYUP:
//处理系统键抬起的消息
ShowKey (hwnd, 0, “WM_SYSKEYUP”, wParam, lParam);
break;
case
ShowKey (hwnd, 1, “WM_SYSCHAR”, wParam, lParam);
break;
case
ShowKey (hwnd, 1, “WM_SYSDEADCHAR”, wParam, lParam);
break;
case WM_DESTROY:
//处理结束应用程序的消息
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
//函数:MyRegisterClass
//作用:注册窗口类
BOOL MyRegisterClass(HINSTANCE hInstance)
{
wnd.cbSize= sizeof (wnd);
wnd.style = CS_HREDRAW | CS_VREDRAW;
wnd.lpfnWndProc = WndProc;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;
wnd.hIcon = LoadIcon (NULL, IDI_APPLICATION);?
wnd.hCursor = LoadCursor (NULL, IDC_ARROW);
wnd.hbrBackground = (HBRUSH)
GetStockObject (WHITE_BRUSH);
wnd.lpszMenuName = NULL;
wnd.lpszClassName = szAppName;
wnd.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
return RegisterClassEx (&wnd);
}
//函数:InitInstance
//作用:创建主窗口
BOOL InitInstance(HINSTANCE hInstance,int iCmdShow)
{
HWND hwnd;
hwnd = CreateWindow (szAppName,
“键盘消息监视程序”,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL
);
if(!hwnd)
{
return FALSE;
}
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
return TRUE;
linux内核如何打开超线程
2.4以后的内核都支持并且默认开启。
通常握晌来说,超线程功能在bios里是默厅友认开启的,
如果你cpu支持超线程,则会自动模拟为物理扮皮槐核心x2;
如果超线程没有开启,可以在开机的时候,进入bios里,找hyper-threading项,改为enabled就是开启超线程
只要BIOS把超线程打开,Linux 2.4以后的内核都支持并且默认开启
首先要在BIOS里面打开超线程支持,然后在Linux内核的Config中打开超线程就可以了。
linux手册翻译——pthread_setname_np()
pthread_setname_np, pthread_getname_np :设置昌滑/获取线程的名称
编译兄迅历和链接需要参数 : -pthread
默认情况下,所有使用 pthread_create() 创建的线程都继承程序名称。 pthread_setname_np() 函数可用于为线程设置唯一名称,这对于调试多线程应用程序非常有用。 线程名称是一个有意义的 C 语言字符串,包括终止空字节 (‘\0’)在内,其长度限制为 16 个字符。
thread
参数指定要更改名称的线程;
name
指定新名称。
pthread_getname_np() 函数可用于获取线程的名称。
thread
参数指定线程。 缓冲区
name
用于存放返回的线程名称; len 指定缓冲区的可用字节数。 区长度至少应为 16 个字符。 输出缓冲区中返回的线程名称将以空 (‘\0’)终止。
成功时,这些函数返回 0; 出错时,它们返回一个非零错误号。
pthread_setname_np() 函数可能会失败并出现以下错误:
ERANGE
name 指定的字符串长度超过了允许的限制。
pthread_setname_np() 函数可能会失败并出现以下错误:
ERANGE
name 和 len 指定的缓冲区太小,无法容纳线程名称。
如果这些函数中的任何一个无法打开 /proc/self/task//comm,则调用可能会失败并出现 open(2) 中描述的错误之一。(见NOTES)
从实现上讲羡搜,pthread_setname_np()将线程的名称写入到了/proc FS的comm文件:/proc/self/task//comm.
关于多线程调试 linux的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。