「指南」多线程调试 Linux:技巧大全 (多线程调试 linux)

多线程调试 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的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《「指南」多线程调试 Linux:技巧大全 (多线程调试 linux)》
文章链接:https://zhuji.vsping.com/31056.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。