【Linux】:封裝線程

朋友們、伙計們,我們又見面了,本期來給大家帶來封裝線程相關的知識點,如果看完之后對你有一定的啟發,那么請留下你的三連,祝大家心想事成!

C 語 言 專 欄:C語言:從入門到精通

數據結構專欄:數據結構

個? 人? 主? 頁?:stackY、

C + + 專 欄? ?:C++

Linux 專?欄? :Linux

??

目錄

引言:

1. 基礎框架?

1.1 初步Start接口

1.2 修正后的Start接口

2. Join接口

?2.1 初步測試

3. 添加模版

4. 全部代碼


引言:

我們想要通過封裝原生線程庫的方式來實現一個類似于C++11里面的線程庫,這里只是為了來更沉入的學習原生線程庫,實現一些基礎的功能即可;

我們創建一個mian.cc文件用于測試線程邏輯;

Thread.hpp主要用于封裝線程;

Makefile主要實現自動化代碼構建。

?

1. 基礎框架?

  • 我們想要封裝的線程需要有對應的線程id、線程名、該線程是否運行以及線程所要執行的任務;
  • 線程所需要執行的任務我們需要用函數包裝器(functional)
  • 我們想要實現的方法有一個讓線程啟動起來的方法,還需要有一個等待線程的方法;
  • 后面根據需要添加對應的成員和方法。

Thread.hpp:

先將基礎框架搭建出來,后面再慢慢補充所需要的接口以及代碼。

1.1 初步Start接口

在Start接口就是用來啟動線程,那么在接口設計中就需要先創建進程,在對應的線程執行方法中執行我們預先設計好的func;

?

?

這里就需要注意一下線程封裝時的細節,我們先來看一下創建線程的接口具體傳遞的參數:

?

我們設置的線程執行方法函數的參數只有一個參數,但是因為我們自己設置的ThreadRoutine函數是類內函數,那么類內函數會默認自己帶一個this指針,所以這于原始函數設計接口不符,所以我們需要將該函數設置為靜態成員函數,然后我們將this指針傳遞給他,然后通過this指針來調用我們預設的func;

1.2 修正后的Start接口

2. Join接口

在實現Join之前我們可以設置一個查看線程是否運行的接口以及獲取線程名的接口,方便后面的測試;

在等待線程這里我們直接使用原生線程庫的接口:

?

我們目前不關心等待的結果;

?2.1 初步測試

上面的代碼算是一份非常簡單的線程封裝代碼,那么接下來我們使用main.cc來使用一下我們封裝的線程庫,因為我們將線程對象化了,所以我們就可以用容器來保存我們的線程,這其實就是一種“先描述,再組織”的過程。

#include <iostream>
#include <unistd.h>
#include <string>
#include <vector>#include "Thread.hpp"
// 設置線程名
std::string GetThreadName()
{static int num = 1;char buffer[64];snprintf(buffer, sizeof(buffer), "Thread-%d", num++);return buffer;
}void Print()
{while(1){std::cout << "hello thread" << std::endl;sleep(1);}
}int main()
{std::vector<Thread> threads;int num = 5;// 創建for(int i = 0; i< num; i++){threads.push_back(Thread(GetThreadName(),Print));}for (auto &t : threads){std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;}// 啟動for (auto &t : threads){t.Start();}for (auto &t : threads){std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;}// Joinfor (auto &t : threads){t.Join();}return 0;
}

3. 添加模版

我們想給我們的線程傳遞參數,所以我們需要添加模版;

整體代碼:

#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>template <class T>
using func_t = std::function<void(T)>; // 任務template <class T>
class Thread
{
public:Thread(const std::string &threadname, func_t<T> func, T data): _tid(0), _thread_name(threadname), _isrunning(false), _func(func), _data(data){}// 執行方法static void* ThreadRoutine(void *args){Thread *ts = static_cast<Thread *>(args);ts->_func(ts->_data);return nullptr;}// 啟動bool Start(){int n = pthread_create(&_tid, nullptr, ThreadRoutine, this); // 將this指針傳遞給ThreadRoutineif(n == 0){_isrunning = true;return true;}else return false;}// 等待bool Join(){if (!_isrunning)return false;int n = pthread_join(_tid, nullptr);if (n == 0){return true;}return false;}bool IsRunning(){return _isrunning;}std::string ThreadName(){return _thread_name;}~Thread() {}private:pthread_t _tid;           // 線程idstd::string _thread_name; // 線程名bool _isrunning;          // 線程是否運行func_t<T> _func;             // 線程所執行任務T _data;                   // 傳遞數據類型
};

4. 全部代碼

Makefile

thread:main.ccg++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -f thread

main.cc

#include <iostream>
#include <unistd.h>
#include <string>
#include <vector>#include "Thread.hpp"
// 設置線程名
std::string GetThreadName()
{static int num = 1;char buffer[64];snprintf(buffer, sizeof(buffer), "Thread-%d", num++);return buffer;
}void Print(int num)
{while(num--){std::cout << "hello thread num :" << num << std::endl;sleep(1);}
}int main()
{Thread<int> t(GetThreadName(), Print, 5);t.Start();t.Join();// std::vector<Thread> threads;// int num = 5;// // 創建// for(int i = 0; i< num; i++)// {//     threads.push_back(Thread(GetThreadName(),Print));// }// for (auto &t : threads)// {//     std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;// }// // 啟動// for (auto &t : threads)// {//     t.Start();// }// for (auto &t : threads)// {//     std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;// }// // Join// for (auto &t : threads)// {//     t.Join();// }// Thread ts(Printf, GetThreadName());// std::cout << "is thread running? " << ts.IsRunning() << std::endl;// ts.Start();// std::cout << "is thread running? " << ts.IsRunning() << std::endl;// ts.Join();return 0;
}

Thread.hpp

#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>template <class T>
using func_t = std::function<void(T)>; // 任務template <class T>
class Thread
{
public:Thread(const std::string &threadname, func_t<T> func, T data): _tid(0), _thread_name(threadname), _isrunning(false), _func(func), _data(data){}// 執行方法static void* ThreadRoutine(void *args){Thread *ts = static_cast<Thread *>(args);ts->_func(ts->_data);return nullptr;}// 啟動bool Start(){int n = pthread_create(&_tid, nullptr, ThreadRoutine, this); // 將this指針傳遞給ThreadRoutineif(n == 0){_isrunning = true;return true;}else return false;}// 等待bool Join(){if (!_isrunning)return false;int n = pthread_join(_tid, nullptr);if (n == 0){return true;}return false;}bool IsRunning(){return _isrunning;}std::string ThreadName(){return _thread_name;}~Thread() {}private:pthread_t _tid;           // 線程idstd::string _thread_name; // 線程名bool _isrunning;          // 線程是否運行func_t<T> _func;             // 線程所執行任務T _data;                   // 傳遞數據類型
};

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

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

相關文章

正則表達式全解析 + Java常用示例

目錄 一、正則表達式基礎&#xff08;一&#xff09;元字符&#xff08;二&#xff09;字符集&#xff08;三&#xff09;量詞 二、正則表達式常用示例&#xff08;一&#xff09;驗證郵箱格式&#xff08;二&#xff09;驗證電話號碼格式&#xff08;三&#xff09;提取網頁中…

LoRa數傳、點對點通信、Mesh網絡、ZigBee以及圖傳技術的區別和特點

以下是LoRa數傳、點對點通信、Mesh網絡、ZigBee以及圖傳技術的區別和特點&#xff1a; 1.LoRa數傳? 特點&#xff1a;LoRa是一種基于擴頻技術的低功耗廣域網&#xff08;LPWAN&#xff09;通信技術&#xff0c;具有傳輸距離遠&#xff08;城市環境可達2-5公里&#xff0c;鄉村…

星越L_三角指示牌及危險警示燈使用

目錄 1.打開危險警告燈 2.取出反光背心穿上 3.取出指示牌 4.放置三角指示牌。 1.打開危險警示燈 2.取出反光背心穿上 3.取出指示牌

AI與人的智能,改變一生的思維模型【7】易得性偏差

目錄 **易得性偏差思維模型&#xff1a;大腦的「熱搜算法」與反操縱指南****病毒式定義&#xff1a;你的大腦正在被「熱搜」劫持****四大核心攻擊路徑與史詩級案例****1. 信息過載時代的「認知短路」****2. 媒體放大器的「恐怖濾鏡」****3. 個人經驗的「數據暴政」****4. 社交繭…

Jmeter的簡單使用

前置工作 確保java8 版本以上jmeter下載路徑&#xff08;選擇Binaries&#xff09;&#xff1a;https://jmeter.apache.org/download_jmeter.cgi直接解壓&#xff0c;找到bin下面的文件&#xff1a;jmeter.bat&#xff08;可選&#xff09;漢化&#xff0c;修改 jmeter.proper…

MyBatis源碼分析の配置文件解析

文章目錄 前言一、SqlSessionFactoryBuilder1.1、XMLConfigBuilder1.2、parse 二、mappers標簽的解析2.1、cacheElement2.1.1、緩存策略 2.2、buildStatementFromContext2.2.1、sql的解析 前言 本篇主要介紹MyBatis源碼中的配置文件解析部分。MyBatis是對于傳統JDBC的封裝&…

golang快速上手基礎語法

變量 第一種&#xff0c;指定變量類型&#xff0c;聲明后若不賦值&#xff0c;使用默認值0 package mainimport "fmt"func main() {var a int //第一種&#xff0c;指定變量類型&#xff0c;聲明后若不賦值&#xff0c;使用默認值0。fmt.Printf(" a %d\n"…

Java中的訪問修飾符有哪些

在 Java 中&#xff0c;訪問修飾符&#xff08;Access Modifiers&#xff09;用于控制類、方法、變量和構造器的訪問權限。Java 提供了四種訪問修飾符&#xff0c;分別是&#xff1a; publicprotecteddefault&#xff08;包私有&#xff0c;沒有顯式修飾符&#xff09;private…

【公務員考試】高效備考指南

高效備考指南&#xff1a;從計劃制定到心態調整的全面攻略 公務員考試競爭激烈&#xff0c;備考過程既需要科學規劃&#xff0c;也需要持之以恒的努力。結合多位高分考生的經驗與專業機構的指導&#xff0c;本文整理了一套系統化的備考策略&#xff0c;涵蓋目標設定、學習方法…

工程實踐:如何使用SU17無人機來實現室內巡檢任務

阿木實驗室最近發布了科研開發者版本的無人機SU17&#xff0c;該無人機上集成了四目視覺&#xff0c;三維激光雷達&#xff0c;云臺吊艙&#xff0c;高算力的機載計算機&#xff0c;是一個非常合適的平臺用于室內外巡檢場景。同時阿木實驗室維護了多個和無人機相關的開源項目。…

強大的CSS變量

在 CSS 中&#xff0c;變量&#xff08;Custom Properties&#xff09; 允許你定義可重用的值&#xff0c;方便在整個樣式表中使用和修改。CSS 變量的基本語法如下&#xff1a; 1. 定義 CSS 變量 CSS 變量通常在 :root 偽類中定義&#xff0c;以便它們可用于整個文檔&#xf…

藍橋杯嵌入式賽道復習筆記1(led點亮)

前言 基礎的文件創建&#xff0c;參賽資源代碼的導入&#xff0c;我就不說了&#xff0c;直接說CubeMX的配置以及代碼邏輯思路的書寫&#xff0c;在此我也預祝大家人人拿國獎 理論講解 原理圖簡介 1.由于存在PC8引腳到PC15引腳存在沖突&#xff0c;那么官方硬件給的解決方案…

Linux進程1.0--task_struct

1.硬件&#xff1a;馮諾依曼體系結構&#xff1a; 單個分析&#xff1a;、 數據流向&#xff1a;數據必須先進入輸入設備&#xff0c;再到存儲器&#xff0c;然后由存儲器給控制器&#xff0c;控制器收到以后進行相應的處理后&#xff0c;再傳回存儲器&#xff0c;存儲器最終傳…

本地部署Jina AI Reader:用Docker打造你的智能解析引擎

本地部署Jina AI Reader&#xff1a;用Docker打造你的智能解析引擎 &#x1f31f; 引言&#xff1a;為什么需要本地部署&#xff1f;&#x1f4cc; 場景應用圖譜&#x1f527; 部署指南&#xff08;Linux環境&#xff09;1. 環境準備2. Docker部署3. 驗證服務狀態 &#x1f680…

貪心算法簡介(greed)

前言&#xff1a; 貪心算法&#xff08;Greedy Algorithm&#xff09;是一種在每個決策階段都選擇當前最優解的算法策略&#xff0c;通過局部最優的累積來尋求全局最優解。其本質是"短視"策略&#xff0c;不回溯已做選擇。 什么是貪心、如何來理解貪心(個人對貪心的…

代碼隨想錄day17 二叉樹part05

654.最大二叉樹 給定一個不重復的整數數組 nums 。 最大二叉樹 可以用下面的算法從 nums 遞歸地構建: 創建一個根節點&#xff0c;其值為 nums 中的最大值。 遞歸地在最大值 左邊 的 子數組前綴上 構建左子樹。 遞歸地在最大值 右邊 的 子數組后綴上 構建右子樹。 返回 nums …

宇樹人形機器人開源模型

1. 下載源碼 https://github.com/unitreerobotics/unitree_ros.git2. 啟動Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 這個錯誤通常出現在虛擬機環境中運行需要OpenGL支持的應用…

通過特征值和特征向量實現的圖像壓縮和特征提取

前文&#xff0c;我們在學習人工智能的線性代數基礎的時候&#xff0c;就了解到&#xff0c;矩陣在人工智能中被廣泛使用&#xff0c;接下來我們就從大家非常常見的圖像開始&#xff0c;深度理解矩陣在人工智能中的應用。有關線性代數基礎的文章可以看的我CSDN:人工智能中的線性…

藍橋杯2023年第十四屆省賽真題-整數刪除 暴力-->鏈表+小根堆

題目來自DOTCPP&#xff1a; 思路&#xff1a; ①每次找到數列中的最小值下標&#xff0c;然后用狀態數組st標記它&#xff0c;相當與刪除它&#xff0c;之后就不會訪問它。 ②對最小值下標左邊和右邊判斷一下&#xff0c;看有沒有數字&#xff0c;如果有就把最小值加到兩邊第…

springboot438-基于SpringBoot的數字化教學資源管理系統(源碼+數據庫+純前后端分離+部署講解等)

&#x1f495;&#x1f495;作者&#xff1a; 愛笑學姐 &#x1f495;&#x1f495;個人簡介&#xff1a;十年Java&#xff0c;Python美女程序員一枚&#xff0c;精通計算機專業前后端各類框架。 &#x1f495;&#x1f495;各類成品Java畢設 。javaweb&#xff0c;ssm&#xf…