【Linux】線程封裝

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

一、為什么需要封裝線程庫?

pthread的痛點:

封裝帶來的好處:

二、線程封裝核心代碼解析

1. 頭文件定義(Thread.hpp)

三、關鍵技術點詳解

1. std::function的魅力

2. 靜態成員函數的巧妙使用

3. 獲取真實的線程ID

四、使用示例和測試代碼

測試代碼(main.cpp)


一、為什么需要封裝線程庫?

在Linux C++開發中,我們經常需要使用多線程。原生的pthread接口雖然強大,但存在一些問題:

pthread的痛點:

  • 🔧?C風格接口:函數指針和void*參數不夠類型安全

  • 📝?冗長的代碼:需要手動管理線程創建、連接、銷毀

  • 🚫?易出錯:容易忘記檢查返回值,導致難以調試的問題

  • 🔄?缺乏RAII:資源管理需要手動處理

封裝帶來的好處:

  • 🎯?類型安全:使用std::function代替函數指針

  • 🚀?簡潔易用:幾行代碼完成線程管理

  • 🛡??異常安全:利用RAII自動管理資源

  • 📦?可擴展性:方便添加新功能(如線程池)

二、線程封裝核心代碼解析

1. 頭文件定義(Thread.hpp)

?

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <functional>
#include <sys/syscall.h>// 獲取輕量級進程ID(線程ID)
#define get_lwp_id() syscall(SYS_gettid)// 定義函數類型別名
using func_t = std::function<void()>;class Thread
{
public:// 構造函數:接收線程函數和線程名Thread(func_t func, const std::string &name): _name(name), _func(func), _isrunning(false){}// 靜態成員函數:線程啟動例程static void *start_routine(void *args){Thread *self = static_cast<Thread *>(args);self->_isrunning = true;self->_lwpid = get_lwp_id();  // 獲取實際線程IDself->_func();                // 執行用戶函數pthread_exit((void *)0);      // 線程退出}// 啟動線程void Start(){int n = pthread_create(&_tid, nullptr, start_routine, this);if (n == 0){std::cout << "線程" << _name << "創建成功" << std::endl;}}// 等待線程結束void Join(){if (!_isrunning) return;int n = pthread_join(_tid, nullptr);if (n == 0){std::cout << "線程" << _name << "回收成功" << std::endl;}}~Thread() {}private:bool _isrunning;        // 線程運行狀態pthread_t _tid;         // 線程IDpid_t _lwpid;           // 輕量級進程IDstd::string _name;      // 線程名稱func_t _func;           // 線程執行函數
};

三、關鍵技術點詳解

1. std::function的魅力

傳統pthread的問題:

?// C風格:需要靜態函數和void*參數
void* thread_func(void* arg) {// 需要類型轉換int* data = (int*)arg;// ...
}

我們的解決方案:

?

// C++11風格:類型安全的函數對象
using func_t = std::function<void()>;// 可以接收任何可調用對象:
// 1. 普通函數
// 2. Lambda表達式  
// 3. 函數對象
// 4. std::bind表達式

2. 靜態成員函數的巧妙使用

為什么需要靜態函數?
pthread_create要求C風格的函數指針,但普通成員函數有隱式的this參數。

解決方案:

?

static void *start_routine(void *args) {Thread *self = static_cast<Thread *>(args);  // 轉換回對象指針self->_func();  // 調用真正的線程函數
}

3. 獲取真實的線程ID

?

#define get_lwp_id() syscall(SYS_gettid)// 為什么需要這個?
// - pthread_t是進程內標識,在不同進程中可能重復
// - 通過系統調用獲取的LWP ID是系統范圍內唯一的
// - 便于調試和系統監控

四、使用示例和測試代碼

測試代碼(main.cpp)

?

#include "Thread.hpp"
#include <iostream>
#include <vector>// 測試函數
void Test()
{int cnt = 3;while (cnt--){std::cout << "線程" << get_lwp_id() << "正在運行..." << std::endl;sleep(1);}
}// Lambda表達式測試
auto lambda_test = []() {std::cout << "Lambda線程運行中" << std::endl;sleep(2);
};int main()
{std::cout << "=== 單線程測試 ===" << std::endl;Thread t1(Test, "single-thread");t1.Start();t1.Join();std::cout << "\n=== 多線程測試 ===" << std::endl;std::vector<Thread> threads;// 創建3個線程for (int i = 0; i < 3; i++){std::string name = "thread-";name += std::to_string(i + 1);threads.emplace_back(Test, name);}// 啟動所有線程for (auto &thread : threads){thread.Start();}// 等待所有線程結束for (auto &thread : threads){thread.Join();}std::cout << "\n=== Lambda測試 ===" << std::endl;Thread t2(lambda_test, "lambda-thread");t2.Start();t2.Join();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97913.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97913.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97913.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

智慧交通管理信號燈通信4G工業路由器應用

在交通信號燈管理中傳統的有線通訊&#xff08;光纖、網線&#xff09;存在部署成本高、偏遠區域覆蓋難、故障維修慢等問題&#xff0c;而4G工業路由器憑借無線化、高穩定、強適配的特性&#xff0c;成為信號燈與管控平臺間的數據傳輸核心&#xff0c;適配多場景需求。智慧交通…

《Python Flask 實戰:構建一個可交互的 Web 應用,從用戶輸入到智能響應》

《Python Flask 實戰:構建一個可交互的 Web 應用,從用戶輸入到智能響應》 一、引言:從“Hello, World!”到“你好,用戶” 在 Web 應用的世界里,最打動人心的功能往往不是炫酷的界面,而是人與系統之間的真實互動。一個簡單的輸入框,一句個性化的回應,往往能讓用戶感受…

開發效率翻倍:資深DBA都在用的MySQL客戶端利器

MySQL 連接工具&#xff08;也稱為客戶端或圖形化界面工具&#xff0c;GUI Tools&#xff09;是數據庫開發、管理和運維中不可或缺的利器。它們比命令行更直觀&#xff0c;能極大提高工作效率。以下是一份主流的 MySQL 連接工具清單&#xff0c;并附上了它們的優缺點和適用場景…

基于Docker和Kubernetes的CI/CD流水線架構設計與優化實踐

基于Docker和Kubernetes的CI/CD流水線架構設計與優化實踐 本文分享了在生產環境中基于Docker和Kubernetes構建高效可靠的CI/CD流水線的實戰經驗&#xff0c;包括業務場景、技術選型、詳細方案、踩坑與解決方案&#xff0c;以及最終的總結與最佳實踐&#xff0c;幫助后端開發者快…

Trae x 圖片素描MCP一鍵將普通圖片轉換為多風格素描效果

目錄前言一、核心工具與優勢解析二、操作步驟&#xff1a;從安裝到生成素描效果第一步&#xff1a;獲取MCP配置代碼第二步&#xff1a;下載第三步&#xff1a;在 Trae 中導入 MCP 配置并建立連接第四步&#xff1a;核心功能調用三、三大素描風格差異化應用四.總結前言 在設計創…

2 XSS

XSS的原理 XSS&#xff08;跨站腳本攻擊&#xff09;原理 1. 核心機制 XSS攻擊的本質是惡意腳本在用戶瀏覽器中執行。攻擊者通過向網頁注入惡意代碼&#xff0c;當其他用戶訪問該頁面時&#xff0c;瀏覽器會執行這些代碼&#xff08;沒有對用戶的輸入進行過濾導致用戶輸入的…

GitHub每日最火火火項目(9.3)

1. pedroslopez / whatsapp-web.js 項目名稱&#xff1a;whatsapp-web.js項目介紹&#xff1a;基于 JavaScript 開發&#xff0c;是一個用于 Node.js 的 WhatsApp 客戶端庫&#xff0c;通過 WhatsApp Web 瀏覽器應用進行連接&#xff08;A WhatsApp client library for NodeJS …

Ansible變量

Ansible變量定義變量規則&#xff1a;由字母/數字/下劃線組成&#xff0c;變量需要以字母開頭&#xff0c;ansible內置的關鍵字不能作為變量。ansible中&#xff0c;可以將變量簡化為三個范圍&#xff1a;Global范圍&#xff08;高&#xff09;&#xff1a;從命令行和ansible配…

Elasticsearch 核心特性與應用指南

最近在準備面試&#xff0c;正把平時積累的筆記、項目中遇到的問題與解決方案、對核心原理的理解&#xff0c;以及高頻業務場景的應對策略系統梳理一遍&#xff0c;既能加深記憶&#xff0c;也能讓知識體系更扎實&#xff0c;供大家參考&#xff0c;歡迎討論。一、核心優勢 Ela…

力扣115:不同的子序列

力扣115:不同的子序列題目思路代碼題目 給你兩個字符串 s 和 t &#xff0c;統計并返回在 s 的 子序列 中 t 出現的個數。 測試用例保證結果在 32 位有符號整數范圍內。 思路 首先我們來考慮特殊情況&#xff0c;當s串的長度小于t串時s串肯定就沒有t串了。其他情況我們就需…

2004-2023年各省生活垃圾無害化處理率數據(無缺失)

2004-2023年各省生活垃圾無害化處理率數據&#xff08;無缺失&#xff09; 1、時間&#xff1a;2004-2023年 2、來源&#xff1a;國家統計局、統計年鑒 3、指標&#xff1a;生活垃圾無害化處理率 4、范圍&#xff1a;30省 5、指標解釋&#xff1a;生活垃圾無害化處理率指報…

【Python練習題】Python小白必練100題答案-第21-40題

練習題直達鏈接Python小白必練100題答案-第1-20題點我直達Python小白必練100題答案-第21-40題點我直達Python小白必練100題答案-第41-60題點我直達Python小白必練100題答案-第61-80題點我直達Python小白必練100題答案-第81-97題點我直達目錄專欄導讀循環結構 字符串操作第三部…

添加?件--場景?

添加?件–場景? 學習到這?&#xff0c;我們已經清楚了如何向倉庫中添加?件&#xff0c;并且對于?作區、暫存區、版本庫也有了?定的認識。那么我們再展??種添加?件的場景&#xff0c;能加深對?作區、暫存區、版本庫的理解&#xff0c;?例如下&#xff1a; roothcss-e…

華為網路設備學習-31(BGP協議 六)

BGP路由屬性的幾種常見使用方法&#xff1a; 29章是 BGP路由匯總 與 as-path-filter&#xff08;正則表達式&#xff09; 30章是 Community 的使用方法 本章是 ip前綴列表ip-prefix 、 路由過濾 filter-policy 和路由策略 route-policy 一、在BGP中的 ip前綴列表&#xf…

Windows PostgreSQL JDBC驅動安裝包位置

要在Windows系統上獲取PostgreSQL JDBC驅動安裝包&#xff08;后綴為.jar的文件&#xff09;&#xff0c;可通過以下官方及常用渠道獲取&#xff0c;具體位置如下&#xff1a; ###&#x1f527; 1. 官方網站下載&#xff08;推薦&#xff09; 下載地址&#xff1a;https://jdb…

機器學習從入門到精通 - 聚類算法大比拼:K-Means、DBSCAN實戰與評估陷阱

機器學習從入門到精通 - 聚類算法大比拼&#xff1a;K-Means、DBSCAN實戰與評估陷阱 開場白&#xff1a;推開無監督學習的大門 朋友們&#xff0c;不知道你們有沒有對著堆積如山、沒有標簽的數據發過愁&#xff1f;想從里面找出點規律&#xff0c;分組什么的&#xff0c;結果發…

AI 重構內容創作:從文案生成到視頻剪輯,創作者該如何與 AI 協同共生?

一、引言&#xff1a;AI 掀起內容創作的 “重構浪潮”?行業現象引入&#xff1a;列舉 AI 在內容創作領域的爆發式應用案例&#xff08;如某平臺 AI 文案工具日生成量破百萬、AI 視頻剪輯軟件用戶增長超 300%&#xff09;?創作者需求變化&#xff1a;通過調研數據說明創作者對…

后端一次性返回十萬條數據時,前端需要采用多種性能優化策略來避免頁面卡頓

當后端一次性返回十萬條數據時&#xff0c;前端需要采用多種性能優化策略來避免頁面卡頓。以下是主要的優化方案&#xff1a; 分頁加載 - 將數據分批次加載顯示虛擬滾動 - 只渲染可視區域內的數據數據懶加載 - 按需加載數據Web Workers - 在后臺線程處理數據時間切片 - 分散渲染…

基于-輕量級文檔搜索系統的測試報告

文章目錄一、項目背景二、項目功能三、測試計劃&#xff08;一&#xff09;測試用例設計&#xff08;二&#xff09;測試用例實現1.功能測試2.界面測試3.兼容性測試4.易用性測試5.安全性測試一、項目背景 1.基于輕量級文檔檢索系統采用C技術棧來實現&#xff0c;同時使用了本地…

編輯器vim(Linux)

Linux下開發工具是獨立的寫代碼——編輯器 vim編譯代碼——gcc/g調試——gdb、cgdb構建工具——makefile、make、cmakevim只用來寫代碼注意&#xff1a;直接用vim打開一個不存在的文件并保存退出&#xff0c;就會自動生成該文件vim有多種模式命令模式&#xff08;Normal Mode&a…