【Linux】線程庫

一、線程庫管理

tid其實是一個地址?

void* start(void* args)
{const char* name = (const char *)args;while(true){printf("我是新線程 %s ,我的地址:0x%lx\n",name,pthread_self());sleep(1);}return nullptr;
}int main()
{pthread_t tid1;pthread_create(&tid1,nullptr,start,(void*)"thread-1");printf("我是主線程,我的地址:0x%lx\n",pthread_self());void* ret = nullptr;pthread_join(tid1,&ret);return 0;
}
zxw@hcss-ecs-cc58:~/linux_-ubuntu/class/lesson7$ ./mythread 
我是主線程,我的地址:0x7f9dbdc333c0
我是新線程 thread-1 ,我的地址:0x7f9dbdc2f640
我是新線程 thread-1 ,我的地址:0x7f9dbdc2f640
我是新線程 thread-1 ,我的地址:0x7f9dbdc2f640

首先,我們知道pthread. h不是操作系統的接口,而是原生線程庫。那么用戶創建的線程,操作系統無法管理,則需要線程庫來進行管理。他從系統中獲取輕量級進程相關屬性,從用戶中也獲取一些屬性,這樣就先描述起來了,再通過數據結構將線程組織起來,就將線程管理好了。

那么線程庫如何管理呢,在哪管理呢???

在進程地址空間中,通過?mmap?(共享區)加載了動態庫,我們使用的?pthread?庫就在該區域。pthread?庫會管理進程中的每一個線程,它使用一系列的數據結構(如線程控制塊)來組織和維護線程的相關信息。

每個線程還擁有獨立的棧空間,主線程的棧由操作系統在進程啟動時自動創建,位于進程地址空間的默認棧區;而通過?pthread_create?創建的其他線程,其棧空間默認由操作系統在進程地址空間的線程私有區域進行分配。

當調用?pthread?相關函數時,實際上是對?pthread?庫所管理的這些數據結構進行訪問和操作,從而實現對線程的創建、同步、銷毀等管理功能。

那么現在,我們也可以理解 pthread_t tid 是什么了,他不就是每一個線程在進程地址空間的起始地址嘛,我們pthread_create 對tid進行寫入,因為需要創建對應的數據結構,找到起始地址,然后返回,后續用戶要繼續對線程進行控制,等待啊,終止啊,分離啊,取消啊。都需要傳入tid,也就是能找到在進程地址空間的位置后,才可以處理。

二、線程的局部存儲?

int g_val = 100;void *TreadFun(void *arg)
{while (1){cout << "我是一個新線程,g_val: " << g_val << ",&g_val: " << &g_val << endl;g_val++;sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(&tid, NULL, TreadFun, (void *)"Thread 1");while (1){cout << "我是一個主線程,g_val: " << g_val << ",&g_val: " << &g_val << endl;sleep(1);}pthread_join(tid,nullptr);
}
zxw@hcss-ecs-cc58:~/linux_-ubuntu/class/lesson7/Pthread$ ./testThread 
我是一個主線程,g_val: 100,&g_val: 0x55a1a3616014
我是一個新線程,g_val: 100,&g_val: 0x55a1a3616014
我是一個主線程,g_val: 101,&g_val: 0x55a1a3616014
我是一個新線程,g_val: 101,&g_val: 0x55a1a3616014
我是一個主線程,g_val: 102,&g_val: 0x55a1a3616014
我是一個新線程,g_val: 102,&g_val: 0x55a1a3616014
我是一個主線程,g_val: 103,&g_val: 0x55a1a3616014
我是一個新線程,g_val: 103,&g_val: 0x55a1a3616014

如果我們給全局變量前添加上__thread,GCC/G++編譯器提供的一個擴展,用于聲明線程局部存儲變量。?

__thread int g_val = 100;

重新執行程序,發現地址發生改變

我是一個主線程,g_val: 100,&g_val: 0x7f8c2a39b3bc
我是一個新線程,g_val: 102,&g_val: 0x7f8c2a39763c
我是一個主線程,g_val: 100,&g_val: 0x7f8c2a39b3bc
我是一個新線程,g_val: 103,&g_val: 0x7f8c2a39763c
我是一個主線程,g_val: 100,&g_val: 0x7f8c2a39b3bc
我是一個新線程,g_val: 104,&g_val: 0x7f8c2a39763c

因為我們添加的__thread 會在G++編譯時,給每個線程的局部存儲空間里將變量拷貝進程,私有一份,于是每個線程自己管理自己的那一份資源。?

__thread只能修飾內置類型,如string這種數據結構和自定義類型無法處理。

?三、線程封裝?

#ifndef _THREAD_HPP__
#define _THREAD_HPP__
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
using namespace std;namespace MyThread
{template <typename T>using func_t = function<void(T)>;static int number = 1;enum TSTATUS{NEW,RUNNING,STOP};template <typename T>class Thread{private:// 成員方法! void* Routinue(Thread* this,void* args)static void *Routinue(void *args){Thread<T> *t = (Thread<T> *)args;t->_status = TSTATUS::RUNNING;t->_func(t->_data);return nullptr;}void EnableDetach(){_joinable = false;}public:Thread(func_t<T> func, T data) : _func(func), _status(TSTATUS::NEW), _joinable(true), _data(data){_name = "Thread-" + to_string(number++);_pid = getpid();}bool Start(){if (_status != TSTATUS::RUNNING){int n = ::pthread_create(&_tid, nullptr, Routinue, this);if (n != 0)return false;return true;}return false;}bool Stop(){if (_status == TSTATUS::RUNNING){int n = ::pthread_cancel(_tid);if (n != 0)return false;return true;}return false;}bool Join(){if (_joinable){int n = ::pthread_join(_tid, nullptr);if (n != 0)return false;_status = TSTATUS::STOP;return true;}return false;}void Detach(){EnableDetach();pthread_detach(_tid);}bool IsJoinable() { return _joinable; }string Name() { return _name; }~Thread(){}private:string _name;pthread_t _tid;pid_t _pid;bool _joinable; // 是否分離,默認不是func_t<T> _func;TSTATUS _status;T _data;};}#endif

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

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

相關文章

深入剖析 Android Compose 框架的自動動畫:AnimatedVisibility 與 AnimatedContent(二十四)

深入剖析 Android Compose 框架的自動動畫&#xff1a;AnimatedVisibility 與 AnimatedContent 引言 在 Android 應用開發中&#xff0c;動畫是提升用戶體驗的重要手段。它能夠讓界面元素的顯示與隱藏、狀態的切換變得更加自然和流暢&#xff0c;避免生硬的變化給用戶帶來不佳…

文件上傳的小點總結(1)

2.文件類型繞過 問題插入&#xff1a;BP無法攔截本地流量 ①插件限制 不代理的地址列表通常寫有localhost和127.0.0.1&#xff0c;把本地的全都刪掉&#xff0c;然后應用保存。 ②瀏覽器限制 Firefox瀏覽器設置&#xff1a;檢查瀏覽器代理配置和proxy listeners都沒問題后&…

AI基礎01-文本數據采集

本篇文章是學習文本數據的采集&#xff0c;作為人工智能訓練師或者數據分析師有時需要先獲取數據&#xff0c;然后進行數據清洗、數據標注。很明顯數據采集是后續步驟的基礎。 1&#xff09;數據采集定義 數據采集&#xff1a;data acquisition&#xff0c;DAQ 又稱為數據獲取…

深度學習Python編程:從入門到工程實踐

第一章 Python語言概述與生態體系 1.3 Python在工業界的應用場景 # 示例:使用FastAPI構建RESTful接口 from fastapi import FastAPI from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: float@app.post("/items/") async def cr…

使用CSS3實現炫酷的3D翻轉卡片效果

使用CSS3實現炫酷的3D翻轉卡片效果 這里寫目錄標題 使用CSS3實現炫酷的3D翻轉卡片效果項目介紹技術要點分析1. 3D空間設置2. 核心CSS屬性3. 布局和定位 實現難點和解決方案1. 3D效果的流暢性2. 卡片內容布局3. 響應式設計 性能優化建議瀏覽器兼容性總結 項目介紹 在這個項目中…

HAl庫開發中斷方式接收Can報文的詳細流程

下面給出一個基于 HAL 庫的中斷方式接收 CAN 報文的詳細流程說明&#xff0c;描述每一步的硬件配置、軟件調用和中斷處理機制&#xff0c;而不涉及具體代碼細節&#xff0c;只講解整體原理和步驟&#xff1a; 在使用 HAL 庫時&#xff0c;不需要手動清除中斷標志位。原因如下&…

【讀書筆記】華為《從偶然到必然》

note 華為的成功并非偶然&#xff0c;而是通過IPD體系、投資組合管理、平臺戰略等系統性工具&#xff0c;將研發投資轉化為可持續的商業競爭力。書中強調的“管理即內部因素”理念&#xff0c;揭示了企業規模擴張與管理能力匹配的深層規律&#xff0c;為高科技企業提供了可借鑒…

6.4考研408數據結構圖論核心知識點深度解析

一、最小生成樹(Minimum Spanning Tree) 1.1 Prim算法 易錯點與難點 lowcost數組更新邏輯 錯誤將已加入生成樹的頂點距離重置為0后繼續參與計算,導致后續頂點選擇錯誤未正確處理非連通圖情況,可能陷入死循環(需結合visited數組判斷)示例錯誤:for(int j=0; j<G.vexn…

HashMap添加元素的流程圖

文章目錄 JDK7 vs JDK8 的 HashMap 結構變化Java8 中哈希表的紅黑樹優化機制HashMap 添加元素的完整流程解析1. 計算 key 的哈希值并確定索引2. 檢查該索引位置是否已有元素3. 處理哈希沖突4. 判斷當前存儲結構&#xff08;鏈表還是紅黑樹&#xff09;5. 判斷鏈表長度是否超過 …

Excel(進階篇):powerquery詳解、PowerQuery的各種用法,逆透視表格、雙行表頭如何制作透視表、不規則數據如何制作數據透視表

目錄 PowerQuery工具基礎修改現有數據理規則PowerQuery抓取數據的兩種方式多文件合并透視不同表結構多表追加數據透視追加與合并整理橫向表格:逆透視 數據用拆分工具整理數據算賬齡 不等步長值組合合并文件夾中所有文件PowerQuery處理CSV文件雙行表頭、帶合并單元格如何做數據…

從零開始:使用 Cython + JNI 在 Android 上運行 Python 算法

1. 引言 在 Android 設備上運行 Python 代碼通常面臨性能、兼容性和封裝等挑戰。尤其是當你希望在 Android 應用中使用 Python 編寫的計算密集型算法時&#xff0c;直接運行 Python 代碼可能導致較高的 CPU 占用和較差的性能。為了解決這個問題&#xff0c;我們可以使用 Cytho…

請為下面的html添加一個修改按鈕,以便對書名、價格進行修改

下面的HTML段落&#xff0c;在書名和價格輸入錯誤的情況下&#xff0c;無法進行修改。添加一個按鈕&#xff0c;對已經輸入的信息進行修改。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></…

FFmpeg + ?Qt? 簡單視頻播放器代碼

一個基于 ?FFmpeg 4.x? 和 ?Qt? 的簡單視頻播放器代碼示例&#xff0c;實現視頻解碼和渲染到 Qt 窗口的功能。 1&#xff09;ffmpeg庫界面&#xff0c;視頻解碼支持軟解和硬解方式。 2&#xff09;QImage/QPixmap顯示視頻圖片。 ?1. Qt 項目配置&#xff08;.pro 文件&…

如何在百度搜索上刪除與自己名字相關的資料

個人信息的網絡足跡如同一張無形的網&#xff0c;將我們與世界的每一個角落緊密相連。然而&#xff0c;當某些與自己名字相關的資料不再希望被公眾輕易檢索到時&#xff0c;如何在百度搜索中有效“隱身”&#xff0c;成為了一個亟待解決的問題。面對復雜多變的網絡環境&#xf…

WebSocket:現代實時通信協議的深度解析與實踐

一、背景與演進歷程 1.1 傳統實時通信的困境 // 典型的HTTP輪詢偽代碼 while(true) {auto response http_client.get("/messages");if(response.has_data()) process(response);std::this_thread::sleep_for(1s); // 固定間隔輪詢 } 高延遲&#xff1a;輪詢間隔導…

[貪心算法]最長回文串 增減字符串匹配 分發餅干

1.最長回文串 我們可以存下每個字母的個數&#xff0c;然后分類討論 如果是奇數就減一加到結果中如果是偶數就直接加入即可 最后判斷長度跟原字符串的差距&#xff0c;如果小于原數組說明有奇數結果1 class Solution { public:int longestPalindrome(string s) {int ret0;//1.計…

STM32 的tf卡驅動

基于STM32的TF卡驅動的基本實現步驟和相關代碼示例,主要使用SPI接口來與TF卡進行通信。 硬件連接 將TF卡的SPI接口與STM32的SPI引腳連接,通常需要連接SCK(時鐘)、MOSI(主出從入)、MISO(主入從出)和CS(片選)引腳。 軟件實現 初始化SPI 配置SPI的工作模式、時鐘頻率…

目標檢測中的非極大值抑制(NMS)原理與實現解析

一、技術背景 在目標檢測任務中&#xff0c;模型通常會對同一目標生成多個重疊的候選框&#xff08;如錨框或預測框&#xff09;。非極大值抑制&#xff08;Non-Maximum Suppression, NMS&#xff09; 是一種關鍵的后處理技術&#xff0c;用于去除冗余的檢測結果&#xff0c;保…

探秘鴻蒙 HarmonyOS NEXT:鴻蒙存儲核心技術全解析

引言 本文章基于HarmonyOS NEXT操作系統&#xff0c;API12以上的版本。 在 ArkTS (ArkUI 框架) 中&#xff0c;用戶首選項 (Preferences) 和 持久化存儲 (PersistentStorage) 都用于數據存儲&#xff0c;但它們有不同的應用場景和特點。 1. 用戶首選項 (Preferences) 概念&a…

Leetcode—15. 三數之和(哈希表—基礎算法)

題目&#xff1a; 給你一個整數數組 nums &#xff0c;判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i ! j、i ! k 且 j ! k &#xff0c;同時還滿足 nums[i] nums[j] nums[k] 0 。請你返回所有和為 0 且不重復的三元組。 注意&#xff1a;答案中不可以包含重復的…