新聞中心
多線程調(diào)試 linux:技巧大全

網(wǎng)站設(shè)計制作過程拒絕使用模板建站;使用PHP+MYSQL原生開發(fā)可交付網(wǎng)站源代碼;符合網(wǎng)站優(yōu)化排名的后臺管理系統(tǒng);網(wǎng)站建設(shè)、網(wǎng)站制作收費合理;免費進行網(wǎng)站備案等企業(yè)網(wǎng)站建設(shè)一條龍服務(wù).我們是一家持續(xù)穩(wěn)定運營了十年的創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司。
在軟件開發(fā)中,多線程編程已經(jīng)成為了非常普遍的技術(shù)。然而,多線程編程也帶來了許多調(diào)試難題,因為多個線程之間的交互以及競爭會導(dǎo)致程序出現(xiàn)意料之外的結(jié)果。為了解決這些問題,你需要掌握一些多線程調(diào)試的技巧。
本文將為你介紹一些常見的多線程調(diào)試技巧,來幫助你定位和解決多線程編程中的問題。
1. 使用調(diào)試器
使用調(diào)試器來調(diào)試多線程程序是最常見的方法。調(diào)試器可以讓你檢查程序中的每個線程,包括它們的堆棧、變量、程序計數(shù)器等。你可以在需要的時候停止或繼續(xù)任何一個或多個線程,并檢查它們在不同時刻的狀態(tài)。
在 Linux 中,你可以使用 GDB 或 CLion 等調(diào)試器來進行多線程調(diào)試。下面是一些使用 GDB 調(diào)試多線程程序的技巧:
– 使用 command 命令創(chuàng)建自定義命令。你可以使用 GDB 的 command 命令來創(chuàng)建自定義命令,這些命令可以用來檢查線程之間的狀態(tài)、設(shè)置斷點等操作。
– 設(shè)置斷點。在多線程程序中,你需要在正確的時機設(shè)置斷點,并檢查每個線程在達到斷點時的狀態(tài)。
– 使用線程列表命令。GDB 的 info threads 命令可以列出所有正在運行的線程,你可以使用該命令來檢查每個線程的狀態(tài)和堆棧信息。
2. 使用 log
如果你的程序中存在未捕獲的異?;蛐盘?,你可以在程序中記錄日志以便后續(xù)分析。在多線程編程中,使用 log 來記錄每個線程的狀態(tài)和行為是非常有用的。你可以使用 log 來記錄以下信息:
– 隊列和緩沖區(qū)的狀態(tài)
– 每個線程的輸入和輸出
– 每個線程的堆棧
你可以使用 syslog 或者其他日志框架來記錄日志。如果你想對每個線程單獨記錄日志,你可以使用線程特定的標(biāo)識符來記錄日志。
3. 使用靜態(tài)分析工具
靜態(tài)分析工具可以幫助你找到程序中的潛在錯誤。在多線程程序中,你可以使用靜態(tài)分析工具來找到以下問題:
– 數(shù)據(jù)競爭:多個線程同時訪問共享資源,導(dǎo)致寫入沖突
– 死鎖:多個線程同時等待同一個鎖,導(dǎo)致無法繼續(xù)執(zhí)行
– 值域錯誤:變量的值不在其有效范圍內(nèi),可能導(dǎo)致內(nèi)存錯誤或者安全問題
在 Linux 中,你可以使用 Clang 或者 Valgrind 等靜態(tài)分析工具來進行多線程程序分析。
4. 使用多線程可視化工具
多線程可視化工具可以幫助你更好地理解程序的執(zhí)行流程。這些工具通常會將每個線程表示為一個顏色編碼的線條或者圖標(biāo),并提供一個時間軸來顯示每個線程的執(zhí)行時間以及線程之間的交互。
在 Linux 中,你可以使用 PARSEC 或者 Camcops 等多線程可視化工具來進行多線程程序分析。
5. 編寫可重現(xiàn)的測試用例
在找出多線程程序中的問題時,編寫可重現(xiàn)的測試用例是非常重要的。一個可重現(xiàn)的測試用例可以讓你輕松地重現(xiàn)程序中的問題,并找到導(dǎo)致程序異常的原因。
在編寫測試用例時,你需要注意以下幾點:
– 在程序中使用固定的隨機種子以確保測試的可重現(xiàn)性
– 嘗試模擬不同的并況,包括競爭和互斥訪問
– 檢查每個線程的狀態(tài),并確保線程之間的互斥訪問正確實現(xiàn)
結(jié)論
在多線程編程中,調(diào)試是一個非常復(fù)雜的過程,需要你掌握大量的技巧。本文介紹了一些常見的多線程調(diào)試技巧,包括使用調(diào)試器、使用 log、使用靜態(tài)分析工具、使用多線程可視化工具以及編寫可重現(xiàn)的測試用例。
使用這些技巧可以幫助你定位和解決程序中的問題,提高程序的穩(wěn)定性和可靠性。同時,也可以增加你在多線程編程方面的經(jīng)驗和技能。
相關(guān)問題拓展閱讀:
- 【求助】linux下的C語言多線程,怎樣監(jiān)視鍵盤上的輸入?
- linux內(nèi)核如何打開超線程
- linux手冊翻譯——pthread_setname_np()
【求助】linux下的C語言多線程,怎樣監(jiān)視鍵盤上的輸入?
發(fā)所用語言為C..
一般的..要想學(xué)好嵌入式開發(fā)..就要兩個都會..
如果只學(xué)linux,這個只是為以后從事linux服務(wù)器搭建,管理和維護等..差不多就是跟硬件打交道..
而嵌入式開發(fā)就相當(dāng)于..在windows下用C,C++,C#,java等開發(fā)一樣..只不過他的開發(fā)平臺換成了linux…
如果想自學(xué)建議按照以下步驟:
學(xué)習(xí)步驟如下:
1、Linux 基礎(chǔ)
安裝Linux操作系統(tǒng)
Linux文件系統(tǒng)
Linux常用命令
Linux啟動過程詳解
熟悉Linux服務(wù)能夠獨立安裝Linux操作系培悔陪統(tǒng)
能夠熟練使用Linux系統(tǒng)的基本命令
認(rèn)識Linux系統(tǒng)的常用服務(wù)安裝Linux操作系統(tǒng)
Linux基本命令實踐
設(shè)置Linux環(huán)境變量
定制Linux的服務(wù) Shell 編程基礎(chǔ)使用vi編輯文件
使用Emacs編輯文件
使用其他編輯器
2、Shell 編程基礎(chǔ)
Shell簡介
認(rèn)識后臺程序
Bash編程熟悉Linux系統(tǒng)下的編輯環(huán)境
熟悉Linux下的各種Shell
熟練進行shell編程熟悉vi基本操作
熟悉Emacs的基本操作
比較不同shell的區(qū)別
編寫一個測試服務(wù)器是否連通的shell腳本程序
編寫一個查看進程是否存在的shell腳本程序
編寫一個帶有循環(huán)語句的shell腳本程序
3、Linux 下的 C 編程基礎(chǔ)
linux C語言環(huán)境概述
Gcc使用方法
Gdb調(diào)試技術(shù)
Autoconf
Automake
Makefile
代碼優(yōu)化 熟悉Linux系統(tǒng)下的開發(fā)環(huán)境
熟悉Gcc編譯器
熟悉Makefile規(guī)則編寫Hello,World程序
使用 make命令編譯程序
編寫帶有一個循環(huán)的程序
調(diào)試一個有問題的程序
4、嵌入式系統(tǒng)開發(fā)基礎(chǔ)
嵌入式系統(tǒng)概述
交叉編譯
配置TFTP服務(wù)
配置NFS服務(wù)
下載Bootloader和內(nèi)核
嵌入式Linux應(yīng)用軟件開發(fā)流程
熟悉嵌入式系統(tǒng)概念以及開發(fā)流程
建立嵌入式系統(tǒng)開發(fā)環(huán)境制作cross_gcc工具鏈
編譯并下載U-boot
編譯并下載Linux內(nèi)核
編譯并下載Linux應(yīng)用程序
嵌入式系統(tǒng)移植
Linux內(nèi)核代碼
平配蠢臺相關(guān)代碼分析
ARM平臺介紹
平臺移植的關(guān)鍵技術(shù)
移植Linux內(nèi)核到 ARM平臺 了解移植的概念
能夠移植Linux內(nèi)核移植Linux2.6內(nèi)核到 ARM9開發(fā)板
5、嵌入式 Linux 下串口通信
串行I/O的基本概念
嵌入式Linux應(yīng)用軟件開發(fā)流程
Linux系統(tǒng)的文件和設(shè)備
與文件相關(guān)的系統(tǒng)調(diào)用
配置超級終端和MiniCOM 能夠熟悉進行串口通信
熟悉文件I/O 編寫串口通信程序
編寫多串口通信程序
6、嵌入式系統(tǒng)中多進程程序設(shè)計
Linux系統(tǒng)進程概述
嵌入式系統(tǒng)的進程特點
進程操作
守護進程
相關(guān)的系統(tǒng)調(diào)用了解Linux系統(tǒng)中進程的概念
能夠編寫多進程程序編寫多進程程序
編寫一個守護進程程序
sleep系統(tǒng)調(diào)用任務(wù)管理、同步與通信 Linux任務(wù)概述
任務(wù)調(diào)度
管道
信號
共享內(nèi)存
任務(wù)管理 API 了解Linux系統(tǒng)任務(wù)管理機制
熟悉進程間通信的幾種方式
熟悉嵌入式Linux中的任務(wù)間同步與通信
編寫一個簡單的管道程序?qū)崿F(xiàn)文件傳輸
編寫前薯一個使用共享內(nèi)存的程序
7、嵌入式系統(tǒng)中多線程程序設(shè)計
線程的基礎(chǔ)知識
多線程編程方法
線程應(yīng)用中的同步問題了解線程的概念
能夠編寫簡單的多線程程序編寫一個多線程程序
8、嵌入式 Linux 網(wǎng)絡(luò)編程
網(wǎng)絡(luò)基礎(chǔ)知識
嵌入式Linux中TCP/IP網(wǎng)絡(luò)結(jié)構(gòu)
socket 編程
常用 API函數(shù)
分析Ping命令的實現(xiàn)
基本UDP套接口編程
許可證管理
PPP協(xié)議
GPRS 了解嵌入式Linux網(wǎng)絡(luò)體系結(jié)構(gòu)
能夠進行嵌入式Linux環(huán)境下的socket 編程
熟悉UDP協(xié)議、PPP協(xié)議
熟悉GPRS 使用socket 編寫代理服務(wù)器
使用socket 編寫路由器
編寫許可證服務(wù)器
指出TCP和UDP的優(yōu)缺點
編寫一個web服務(wù)器
編寫一個運行在 ARM平臺的網(wǎng)絡(luò)播放器
9、GUI 程序開發(fā)
GUI基礎(chǔ)
嵌入式系統(tǒng)GUI類型
編譯QT
進行QT開發(fā)熟悉嵌入式系統(tǒng)常用的GUI
能夠進行QT編程使用QT編寫“Hello,World”程序
調(diào)試一個加入信號/槽的實例
通過重載QWidget 類方法處理事件
10、Linux 字符設(shè)備驅(qū)動程序
設(shè)備驅(qū)動程序基礎(chǔ)知識
Linux系統(tǒng)的模塊
字符設(shè)備驅(qū)動分析
fs_operation結(jié)構(gòu)
加載驅(qū)動程序了解設(shè)備驅(qū)動程序的概念
了解Linux字符設(shè)備驅(qū)動程序結(jié)構(gòu)
能夠編寫字符設(shè)備驅(qū)動程序編寫Skull驅(qū)動
編寫鍵盤驅(qū)動
編寫I/O驅(qū)動
分析一個看門狗驅(qū)動程序
對比Linux2.6內(nèi)核與2.4內(nèi)核中字符設(shè)備驅(qū)動的不同
Linux 塊設(shè)備驅(qū)動程序塊設(shè)備驅(qū)動程序工作原理
典型的塊設(shè)備驅(qū)動程序分析
塊設(shè)備的讀寫請求隊列了解Linux塊設(shè)備驅(qū)動程序結(jié)構(gòu)
能夠編寫簡單的塊設(shè)備驅(qū)動程序比較字符設(shè)備與塊設(shè)備的異同
編寫MMC卡驅(qū)動程序
分析一個文件系統(tǒng)
對比Linux2.6內(nèi)核與2.4內(nèi)核中塊設(shè)備驅(qū)動的不同
11、文件系統(tǒng)
虛擬文件系統(tǒng)
文件系統(tǒng)的建立
ramfs內(nèi)存文件系統(tǒng)
proc文件系統(tǒng)
devfs 文件系統(tǒng)
MTD技術(shù)簡介
MTD塊設(shè)備初始化
MTD塊設(shè)備的讀寫操作了解Linux系統(tǒng)的文件系統(tǒng)
了解嵌入式Linux的文件系統(tǒng)
了解MTD技術(shù)
能夠編寫簡單的文件系統(tǒng)為 ARM9開發(fā)板添加 MTD支持
移植JFFS2文件系統(tǒng)
通過proc文件系統(tǒng)修改操作系統(tǒng)參數(shù)
分析romfs 文件系統(tǒng)源代碼
創(chuàng)建一個cramfs 文件系統(tǒng)
望采納:可是一個字一個字錢敲出來的..
另外,站長團上有產(chǎn)品團購,便宜有保證
在襪沖Microsoft Windows 中,鍵盤和鼠標(biāo)是兩個標(biāo)準(zhǔn)的用戶輸入源,在一些交疊的操作中通常相互補充使用。當(dāng)然,鼠標(biāo)在今天的應(yīng)用程序中比10年前使用得更為廣泛。甚至在一些應(yīng)用程序中,我們更習(xí)慣于使用鼠標(biāo),例如在游戲、畫圖程序、音樂程序,以及Web創(chuàng)覽器等程序中就是這樣。然而,我們可以不使用鼠標(biāo),但絕對不能從一般的PC中拆掉鍵盤。
Windows程序獲得鍵盤輸入的方式:鍵盤輸入以消息的形式傳遞給程序的窗口過程。實際上,之一次學(xué)習(xí)消息時,鍵盤就是一個明顯的例子:消息應(yīng)該傳遞給應(yīng)用程序的信息類型。
Windows用8種不同的消息來傳遞不同的鍵盤事件。這好像太多了,但是(如野就像我們所看到的一樣)程序可以忽略其中至少一半的消息而不會有任何問題。并且,在大多數(shù)情況下,這些消息中包含的鍵盤信息會多于程序所需要的。處理鍵盤的部分工作就是識別出哪些消息是重要的,哪些是不重要的。
鍵盤基礎(chǔ)知識
雖然應(yīng)用程序在很多情況下可以通過鼠標(biāo)實現(xiàn)信息的輸入,但到現(xiàn)在為止鍵盤仍然是PC機中不可替代的重要輸入設(shè)備。
用鍵盤當(dāng)作輸入設(shè)備,每當(dāng)用戶按下或釋放某一個鍵時,會產(chǎn)生一個中斷,該中斷激活鍵盤驅(qū)動程序KEYBOARD.DRV來對鍵盤中斷進行處理。 KEYBOARD.DRV程序會根據(jù)用戶的不同操作進行編碼,然后調(diào)用Windows用戶模塊USER.EXE生成鍵盤消息,并將該消息發(fā)送到消息隊列中等候處理。
1.掃描碼和虛擬碼
掃描碼對應(yīng)著鍵盤上的不同鍵,每一個鍵被按下或釋放時,都會產(chǎn)生一個唯一的掃描碼作為本身的標(biāo)識。掃描碼依賴于具體的硬告橡殲件設(shè)備,即當(dāng)相同的鍵被按下或釋放時,在不同的機器上可能產(chǎn)生不同的掃描碼。在程序中通常使用由Windows系統(tǒng)定義的與具體設(shè)備無關(guān)的虛擬碼。在擊鍵產(chǎn)生掃描碼的同時,鍵盤驅(qū)動程序KEYBOARD.DRV截取鍵的掃描碼,然后將其翻譯成對應(yīng)的虛擬碼,再將掃描碼和虛擬碼一齊編碼形成鍵盤消息。所以,最后發(fā)送到消息隊列的鍵盤消息中,既包含了掃描碼又包含了虛擬碼。
經(jīng)常使用的虛擬碼在WINDOWS.H文件中定義,常用虛擬碼的數(shù)值、常量符號和含義如表所示。
取值(16進制) 常量符號 含義
VK_LBUTTON 鼠標(biāo)左鍵
VK_RBUTTON 鼠標(biāo)右鍵
VK_CANCEL Break中斷鍵
VK_MBUTTON 鼠標(biāo)中鍵
未定義
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鍵
漢字系統(tǒng)保留
1A — 未定義
1B VK_ESCAPE Esc鍵
1C-1F — 漢字系統(tǒng)保留
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 數(shù)字鍵0-9
3A未定義
A VK_A-VK_Z 字母鍵A-Z
5B-5F — 未定義
VK_NUMPAD0-VK_NUMPAD9 小鍵盤數(shù)字鍵0-9
6A VK_MULTIP *(乘號)鍵
6B VK_ADD +(加號)鍵
6C VK_SEPAPATOR 分隔符鍵
6E VK_SURACT -(減號)鍵
6F VK_DECIMAL .(小數(shù)點)鍵
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中可能有多個不同的程序在運行,也就是說有多個窗口同時存在。這時,鍵盤由多個窗口共享,但只有一個窗口能夠接收到鍵盤消息,這個能夠接收鍵盤消息的窗口被稱為擁有輸入焦點的窗口。
擁有輸入焦點的窗口應(yīng)該是當(dāng)前的活動窗口,或者是活動窗口的子窗口,其標(biāo)題和邊框會以高亮度顯示,以區(qū)別于其他窗口。擁有輸入焦點的也可以是圖標(biāo)而不是窗口,此時,Windows也將消息發(fā)送給圖標(biāo),只是消息的格式略有不同。
窗口過程可以通過發(fā)送WM_SETFOCUS和 WM_KILLFOCUS消息使窗體獲得或失去輸入焦點。程序也可以通過捕獲WM_SETFOCUS和WM_KILLFOCUS消息來判斷窗體何時獲得或失去輸入焦點。其中WM_SETFOCUS消息表示窗口正獲得輸入焦點,WM_ KILLFOCUS消息表示窗口正失去輸入焦點。
3.鍵盤消息
鍵盤消息分為系統(tǒng)鍵消息和非系統(tǒng)鍵消息。系統(tǒng)鍵消息是指由Aft鍵和其他鍵組合而產(chǎn)生的按鍵消息。當(dāng)系統(tǒng)鍵被按下時產(chǎn)生WM_ SYSKEYDOWN消息,當(dāng)系統(tǒng)鍵被釋放時產(chǎn)生WM_SYSKEYUP消息。 Aft鍵與其他鍵形成的組合鍵通常用于對程序菜單和系統(tǒng)菜單進行選擇,或用于在不同的程序之間進行切換。因此,系統(tǒng)鍵消息應(yīng)該交由Windows進行處理,用戶所編制的程序一般不處理系統(tǒng)鍵消息,而是將這些消息交由DefWindowProc函數(shù)進行處理。如果用戶想對系統(tǒng)鍵消息進行處理,應(yīng)該在處理完這些消息后,再將其發(fā)送給DefWindowProc函數(shù),使得Windows系統(tǒng)能夠正常工作。
某些擊鍵消息可以被轉(zhuǎn)換成字符消息,例如字母鍵、數(shù)字鍵等。而有些鍵只能產(chǎn)生按鍵消息而沒有字符消息,例如 Shift鍵、Insert鍵等。消息循環(huán)中的 TranslateMessage函數(shù)可以實現(xiàn)從擊鍵消息向字符消息的轉(zhuǎn)化。當(dāng)GetMessage函數(shù)捕獲一個WM_SYSKEYDOWN消息或 WM_KEYDOWN消息后,TranslateMessage函數(shù)判斷產(chǎn)生該消息的鍵是否能夠被轉(zhuǎn)換成字符消息,如果能,就將該消息轉(zhuǎn)換成字符消息,再通過DispatchMessape函數(shù)將轉(zhuǎn)換后的字符消息發(fā)送到消息隊列中去。字符消息共有以下四種,如表所示。
字符 系統(tǒng)字符 非系統(tǒng)字符
普通字符 WM_SYSCHAR WM_CHAR
死字符 WM_SYSDEADCHAR WM_DEADCHAR
其中死字符是由某些特殊鍵盤上的按鍵所造成的,Windows一般忽略死字符所產(chǎn)生的消息。
Windows的消息一般是通過一個MSG結(jié)構(gòu)體變量傳送給消息處理函數(shù)的。對于鍵盤消息, MSG結(jié)構(gòu)體變量的各個域中較重要的是lParam域和 wParam域。wParam域用于保存按鍵的虛擬鍵代碼或字符的ASCII碼。對于非字符消息,wParam域保存按鍵的虛擬健代碼;對于字符消息, wParam域不保存字符的ASCII碼。lParam域則用于保存擊鍵時產(chǎn)生的附加信息,實際上一個32位的lParam變量被分為六部分,記錄了以下相關(guān)信息:重復(fù)次數(shù)、OEM掃描碼、擴展鍵標(biāo)志、關(guān)聯(lián)鍵標(biāo)志、前一擊鍵狀態(tài)和轉(zhuǎn)換狀態(tài)。lParam域各位的含義如表所示。
位數(shù) 含義
擊鍵重復(fù)次數(shù)累加
OEM掃描碼
是否為擴展鍵
未定義
是否便用關(guān)聯(lián)鍵,及Alt鍵是否同時按下。
前一次擊鍵狀態(tài),0表示該鍵前一次狀態(tài)為抬起,1表示前一次狀態(tài)為按下
轉(zhuǎn)換狀態(tài)
按鍵的次序不同,產(chǎn)生的消息也不相同。例如,按下并釋放1鍵,讀過程依次產(chǎn)生如表所示三條消息。按下1鍵所產(chǎn)生的消息和wParam的取值
消息 wParam變量取值
WM_KEYDOWN 虛擬碼1
WM_CHAR ASCII碼“1”
WM_KEYUP 虛擬碼1
如果按下Shift鍵后再按下1鍵并釋放,則依次產(chǎn)生如表所示的消息。按下 Shift鍵后按 1健所產(chǎn)生的消息和 wParam的取值
消息 wParam變量取值
WM_KEYDOWN 虛擬碼 VK_SHIFT
WM_KEYDOWN 虛擬碼 VK_1
WM_CHAR ASCII碼 “1”
WM_KEYUP 虛擬碼 VK_1
WM_KEYUP 虛擬碼 VK_SHIF
鍵盤應(yīng)用實例
下面通過一個應(yīng)用程序?qū)嵗齺碚f明在實際編程中如何處理鍵盤消息。
#include
#include
// 全局變量
RECT rc; //記錄滾屏的矩形區(qū)域
?
int xChar, yChar; //文本輸入點坐標(biāo)
WNDCLASSEX wnd; //窗口類結(jié)構(gòu)變量
char szAppName = “鍵盤消息監(jiān)視程序”; //窗口類名
//函數(shù)聲明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance,int iCmdShow);
//函數(shù):WinMain
//作用:入口函數(shù)
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;
}
//函數(shù):ShowKey
//作用:實現(xiàn)在窗口中顯示按鍵信息
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), // 重復(fù)次數(shù)
HIWORD (lParam) & 0xFF, // OEM鍵盤掃描碼
//判斷是否為增強鍵盤的擴展鍵
(PSTR) (0x& lParam ? “是” : “否”),
//判斷是否同時使用了ALT鍵
(PSTR) (0x& lParam ? “是” : “否”),
(PSTR) (0x& lParam ? “按下” : “抬”),
//判斷前一次擊鍵狀
(PSTR)(0x& lParam ? “按下” : “抬起”))
//判斷轉(zhuǎn)換狀態(tài)?
);
ReleaseDC (hwnd, hdc); ?
ValidateRect (hwnd, NULL); ?
}
//函數(shù):WndProc
//作用:處理主窗口的消息
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static char szTop =”消息鍵 字符 重復(fù)數(shù) 掃描碼 擴展碼 ALT 前一狀態(tài) 轉(zhuǎn)換狀態(tài)”;
static char szUnd =”_______ __ ____ _____ ______ ______ ___ _______ ______”;
//在窗口中輸出文字作為信息標(biāo)題
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
switch (iMsg)
{
case
hdc = GetDC (hwnd); //設(shè)定字體
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)); //檢取當(dāng)前字體的度量數(shù)據(jù)
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;//保存字體平均寬度
yChar = tm.tmHeight; //保存字體高度
ReleaseDC (hwnd, hdc);
rc.top = 3 * yChar / 2;
return 0;
case
//窗體改變后保存新的滾屏區(qū)域右下角坐標(biāo)
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:
//處理擊鍵過程中產(chǎn)生的非系統(tǒng)鍵的可見字符消息
howKey (hwnd, 1, “WM_CHAR”, wParam, lParam);
return 0;
case WM_DEADCHAR:
//處理擊鍵過程中產(chǎn)生的非系統(tǒng)鍵”死字符”消息
ShowKey (hwnd, 1, “WM_DEADCHAR”, wParam, lParam);
return 0;
case WM_SYSKEYDOWN:
//處理系統(tǒng)鍵按下的消息
ShowKey (hwnd, 0, “WM_SYSKEYDOWN”,wParam, lParam);
break;
case WM_SYSKEYUP:
//處理系統(tǒng)鍵抬起的消息
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:
//處理結(jié)束應(yīng)用程序的消息
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
//函數(shù):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);
}
//函數(shù):InitInstance
//作用:創(chuàng)建主窗口
BOOL InitInstance(HINSTANCE hInstance,int iCmdShow)
{
HWND hwnd;
hwnd = CreateWindow (szAppName,
“鍵盤消息監(jiān)視程序”,
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內(nèi)核如何打開超線程
2.4以后的內(nèi)核都支持并且默認(rèn)開啟。
通常握晌來說,超線程功能在bios里是默廳友認(rèn)開啟的,
如果你cpu支持超線程,則會自動模擬為物理扮皮槐核心x2;
如果超線程沒有開啟,可以在開機的時候,進入bios里,找hyper-threading項,改為enabled就是開啟超線程
只要BIOS把超線程打開,Linux 2.4以后的內(nèi)核都支持并且默認(rèn)開啟
首先要在BIOS里面打開超線程支持,然后在Linux內(nèi)核的Config中打開超線程就可以了。
linux手冊翻譯——pthread_setname_np()
pthread_setname_np, pthread_getname_np :設(shè)置昌滑/獲取線程的名稱
編譯兄迅歷和鏈接需要參數(shù) : -pthread
默認(rèn)情況下,所有使用 pthread_create() 創(chuàng)建的線程都繼承程序名稱。 pthread_setname_np() 函數(shù)可用于為線程設(shè)置唯一名稱,這對于調(diào)試多線程應(yīng)用程序非常有用。 線程名稱是一個有意義的 C 語言字符串,包括終止空字節(jié) (‘\0’)在內(nèi),其長度限制為 16 個字符。
thread
參數(shù)指定要更改名稱的線程;
name
指定新名稱。
pthread_getname_np() 函數(shù)可用于獲取線程的名稱。
thread
參數(shù)指定線程。 緩沖區(qū)
name
用于存放返回的線程名稱; len 指定緩沖區(qū)的可用字節(jié)數(shù)。 區(qū)長度至少應(yīng)為 16 個字符。 輸出緩沖區(qū)中返回的線程名稱將以空 (‘\0’)終止。
成功時,這些函數(shù)返回 0; 出錯時,它們返回一個非零錯誤號。
pthread_setname_np() 函數(shù)可能會失敗并出現(xiàn)以下錯誤:
ERANGE
name 指定的字符串長度超過了允許的限制。
pthread_setname_np() 函數(shù)可能會失敗并出現(xiàn)以下錯誤:
ERANGE
name 和 len 指定的緩沖區(qū)太小,無法容納線程名稱。
如果這些函數(shù)中的任何一個無法打開 /proc/self/task//comm,則調(diào)用可能會失敗并出現(xiàn) open(2) 中描述的錯誤之一。(見NOTES)
從實現(xiàn)上講羨搜,pthread_setname_np()將線程的名稱寫入到了/proc FS的comm文件:/proc/self/task//comm.
關(guān)于多線程調(diào)試 linux的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機、虛擬主機、域名注冊、VPS主機、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
網(wǎng)頁標(biāo)題:「指南」多線程調(diào)試Linux:技巧大全(多線程調(diào)試linux)
文章地址:http://www.fisionsoft.com.cn/article/dpijeje.html


咨詢
建站咨詢
