線程的學習

1. 線程

1. 線程是一個進程內部的控制序列

2. 線程在進程內部運行,本質是在進程地址空間內運行

3. 進程:承擔分配系統資源的基本實體

? ? 線程:CPU調度的基本單位

4. 線程在進程地址空間內運行

? ? 進程訪問的大部分資源都是通過地址空間訪問的

5. 在硬件CPU視角:線程是輕量級進程

? ? ?Linux操作系統視角:執行流

? ? ?執行流 <= 進程

6. 將資源合理分配給每一個執行流,就形成了線程執行流

7. 一切進程至少都有一個執行線程


總結:

1. 線程可以采用進程來模擬

2. 對資源的劃分本質是對地址空間虛擬地址范圍的劃分。虛擬地址就是資源的代表

3. 函數就是虛擬地址(邏輯地址)空間的集合,就是讓線程未來執行ELF程序的不同函數

4. linux的線程就是輕量級進程,或者用輕量級進程模擬實現的

5. 如果把家庭比作進程,那么家庭的每個成員就都是線程

進程強調獨占,部分共享(通信的時候)

線程強調共享,部分獨占


4KB內存與頁框:

物理內存以4KB為單位被劃分成一個一個的頁框

在進行I/O操作時,數據也是以4KB為單位在內存和磁盤間交換(程序需要讀取磁盤數據時也是以4KB大小的塊來讀取)

要管理這些4KB的頁框,也是先描述再組織

申請物理內存是在做什么?

1.查數組,改page(頁)

2.建立內核數據結構的對應關系

struck page是一個自定義描述物理內存中頁的結構體

struct page mem[1048576];

聲明了一個包含1048576個類型為struct page的元素的mem數組,每個page都有下標

4GB=4*1024*1024 KB

4*1024*1024KB/4KB = 1048576

每個page的起始物理地址就在獨立,具體物理地址=起始物理地址+頁(4KB)內偏移

沒有使用的page標志位為0


劃分地址空間本質就是劃分虛擬地址

在cpu視角全部都是輕量級進程

OS管理的基本單位是4KB


頁表(本質是一張虛擬到物理的地圖)的地址轉換

虛擬地址(邏輯地址) 轉化為物理地址

32位的數字

0000000000 0000000000 000000000000? ? ? ? ? ? ? ? ? ? ? ??
[0,1024)? ? ? ? [0,1024)? ? ? ? ? ? ?[0,4096]

CR3寄存器讀取頁目錄起始位置,根據一級頁號查頁目錄表

前10個bit位的縮影查到頁目錄

頁目錄里存儲的是下一級頁表的地址,每一項對應一個二級頁表,定位到下一級頁表的位置

頁目錄中的項可以理解為一種指針

二級頁表里面存儲的是物理頁框的地址,用于實現虛擬地址和物理地址間映射的關鍵

低12位為頁內偏移

4KB頁面大小意味著每個頁面有4096個字節單位,12位二進制數可表示為2^12 = 4096 個不同地址,可以用低12位去充分覆蓋一個頁框的整個范圍,可唯一標識頁面內的每個字節單元

先查到虛擬地址對應的頁框,根據虛擬地址的低12位作為頁內偏移訪問具體字節


一些細節:

1. 內存申請->查找數組->找到沒有被使用的page(標志位為0)->page

index(索引)->物理頁框地址

2. 寫實拷貝,缺頁中斷,內存申請等,背后都可能要重新建立新的頁表和建立映射關系的操作

3. 進程,一張頁目錄+n張頁表構建的映射關系,虛擬地址是索引,物理地址頁框是目標

物理地址=頁框地址+虛擬地址(低12位)


線程的深刻理解

執行流看到的資源是在合法情況下擁有的合法虛擬地址,虛擬地址就是資源的代表

虛擬地址空間本質:進行資源的統計數據還和整體數據

資源劃分:本質就是地址空間劃分

資源共享:本質就是虛擬地址的共享

線程進行資源劃分:本質是劃分地址空間,獲得一定范圍的合法虛擬地址,在本質,就是劃分頁表

線程進行資源共享:本質是對地址空間的共享,在本質就是對頁表條目的共享


申請內存也就是申請地址空間

越界不一定報錯


優點:

線程切換:

線程之間的切換需要OS做的工作比進程要少很多

線程切換虛擬地址空間依然是相同的

線程切換時不用對CR3寄存器進行保存
線程切換不會導致緩存失效

進程切換:

指針指向我們選中的進程,OS想知道當前進程是誰,找到該指針,優化到cpu寄存器中

進程切換=>cpu硬件上下文切換

會導致TLB和Cache失效,下次運行,需要重新緩存

線程占用的資源比進程少?線程拿到的資源本身就是進程的一部分,線程是更輕量化的


2. 進程VS線程

進程是資源分配的基本單位

線程是調度的基本單位

線程共享進程數據,但也擁有自己的一部分數據

1.線程ID

2.一組寄存器,線程的上下文數據

3.棧

4.erno

5.信號屏蔽字

6.調度優先級


3. linux 線程控制

創建線程

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);//thread :返回線程id
//attr:設置線程屬性
//start_routine:是個函數地址,線程啟動后要執行的函數
//arg:傳給線程啟動函數的參數

線程創建好之后,新線程要被主線程等待(類似僵尸進程的問題,內存泄漏)

代碼:

?PID:進程ID

LWP:? 輕量級進程ID

這意味著進程內有多個線程,每個線程對應一個LWP號

CPU調度的時候,看輕量級進程lwp

1.關于調度的時間片問題:時間等分給不同的線程

2.任何一個線程崩潰,都會導致整個進程崩潰

線程tid:不直接暴露lwp概念

#include <iostream>
#include <cstdio>
#include <string>
#include <unistd.h>
#include <pthread.h>void showtid(pthread_t &tid)
{printf("tid: 0x%lx\n",tid);
}
std::string FormatId(const pthread_t &tid)
{char id[64];snprintf(id, sizeof(id), "0x%lx", tid);return id;
}
void *routine(void *args)
{std::string name = static_cast<const char*>(args);pthread_t tid = pthread_self();int cnt = 3;while(cnt){std::cout << "我是一個新線程: my name: main thread "  << " 我的Id:  " << FormatId(tid) << std::endl;sleep(1);cnt--; }return nullptr;
}int main()
{pthread_t tid;//tid變量用于存儲新創建進程的標識符int n = pthread_create(&tid, nullptr, routine, (void*)"thread-1");(void)n;showtid(tid);int cnt = 3;while(cnt){std::cout << "我是main線程: my name: main thread " << " 我的Id:  " << FormatId(pthread_self()) << std::endl;sleep(1);cnt--; }pthread_join(tid,nullptr);//等待進程結束return 0;
}

main函數也有自己的線程id


pthread庫,把創建輕量級進程封裝起來,給用戶提供一批創建線程的接口

linux線程實現是在用戶層實現的,我們稱之為用戶級線程

pthread:原生線程庫

C++的多線程,在linux下,本質是封裝了pthread庫,在windows下封裝windows創建線程的接口

linux系統,不存在真正意義上的線程,他所謂的概念,使用輕量級進程模擬的,但OS中,只有輕量級進程,所謂的模擬線程是我們的說法,linux只會給我們提供創建輕量級進程的系統調用


pthread_exit函數

線程終止


pthread_cancel

取消一個執行中的線程

取消的時候一定要保證線程已經啟動


pthread_join

等待線程結束

資源回收,線程終止時,系統不會自動回收線程資源,直到有其他線程調用該函數,目標線程的資源會被徹底釋放。

//thread:要等待的線程id

//retval:二級指針,用于存儲目標線程的返回值

pthread_join() 函數必須由其他線程調用,用于回收目標終止線程的資源

只能由當前線程以外的其他線程調用。例如:
主線程可以調用 pthread_join() 回收子線程的資源
子線程 A 可以調用 pthread_join() 回收子線程 B 的資源

通過函數參數指定要回收的目標線程 ID(tid)


線程分離

線程分離是一種管理線程資源的機制,當線程被設置為分離狀態時,它終止后會自動釋放所有資源,不需要有其他線程調用pthread_join來回收資源

線程的狀態:1.Joinable 可結合的 新創建的線程是可結合的,需要對其進行pthread_join操作來回? ? ? ? ? ? ? ? ? ? ? ? ? ?收資源,避免資源泄露

? ? ? ? ? ? ? ? ? ? ? 2.Detached 分離的

------------------------------------------------------------------------------------------------------------------------------------------------------------

linux沒有真正的線程,他是用輕量級進程模擬的

os提供的接口,不會直接提供線程接口

在用戶層,封裝輕量級進程形成原生線程庫(用戶級別的庫)

linux所有線程,都在庫中

線程的概念是在庫中維護的,在庫內部就一定會存在多個被創建好的線程,庫管理線程也是先描述再組織

? ? ? ? ? ? ? ? ? ?pthread_create()

struct tcb

? ? ? ? //線程應該有的屬性

? ? ? ? 線程狀態

? ? ? ? 線程id

? ? ? ? 線程獨立的棧結構

? ? ? ? 線程棧大小

線程自己的代碼區可以訪問到pthread庫內部的函數或數據

linux所有線程都在庫中


顯示器文件本身就是共享資源

拿到新線程的退出信息

線程測試

線程能夠執行進程的一部分

創建多線程


為什么是9?給每個線程第一傳id,大家的地址都一樣,所有線程參數指向的空間都是同一個,每創建一個進程都要覆蓋式改這個id,創建的這個id會讓所有線程都看到,拿到的都是同一個地址,指向的是同一個64位的空間,所以進行對應的寫入時就把上一次的覆蓋了


每一次循環要給每一個線程申請一段堆空間,這個堆空間雖然也是共享的,但只有改=該線程知道空間的起始地址

創建訪問線程的本質就是訪問用戶級別的庫


描述線程的管理塊

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pthread庫在內存中


只需要描述我們線程有關的id信息

創建一個描述線程的管理塊,有三部分構成,返回時,返回的id地址就是這個塊的起始地址

需要jion,因為線程結束時,只是函數結束了,但是在庫中線程管理塊并沒有結束

tid(退出的線程管理塊的起始地址/線程在庫中,對應的管理快塊的虛擬地址)和ret(曾經線程退出時的結果)就拿到整個線程退出時的退出信息,再把該線程的管理塊全部釋放,得到返回結果同時解決內存泄漏問題

在自己的代碼區里調create(),其實是在動態庫內部創建描述該線程的管理塊,管理塊的開頭是線程tcb,里面包含了線程的相關信息,tcb里包含了void *ret字段。當當前線程運行的時候,運行結束會把返回值拷貝到自己線程控制塊的void *ret。新主線程都共享地址空間,只要拿到起始虛擬地址,就可以拿到退出線程的控制塊

每個線程都有自己獨立的棧空間


clone是用于創建進程/線程的函數,可以看作是fork的升級版

 #define _GNU_SOURCE#include <sched.h>int clone(int (*fn)(void *), void *stack, int flags, void *arg, .../* pid_t *parent_tid, void *tls, pid_t *child_tid */ );

fn:子進程/線程的入口函數

linux所有線nn

linux用戶級線程:內核級LWP = 1:1

主線程和新線程誰先運行是不確定的

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

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

相關文章

Qt Quick 與 QML(三)qml中的基礎控件

一、基礎控件 控件名稱??功能描述??示例代碼??Rectangle?基礎繪圖控件&#xff0c;創建矩形區域Rectangle {width: 100; height: 100<br> color: "red"; radius: 5}?Text/Label?文本顯示控件Text {text: "Hello World";<br> font.pi…

Redis實現消息隊列全解析:從基礎到高級應用實戰

目錄 一、Redis作為消息隊列的優勢與局限 1.1 核心優勢 1.2 適用場景 1.3 局限性及解決方案 二、Redis消息隊列實現方案對比 三、List實現基礎消息隊列 3.1 生產者實現原理 3.2 消費者實現原理 3.3 可靠性增強&#xff1a;ACK機制 四、Pub/Sub實現發布訂閱 4.1 消息發…

Windows應用商店中的國學啟蒙教育應用

國學啟蒙是中國傳統文化教育的重要組成部分&#xff0c;主要以經典誦讀、傳統禮儀、歷史故事等內容為載體&#xff0c;向兒童傳遞中華文化的核心價值觀。幫助孩子建立文化認同感&#xff0c;培養良好的道德觀念和行為習慣。通過學習古代圣賢的言行&#xff0c;兒童可以初步理解…

安科瑞UL認證ADL3000-E/C導軌表:工商業儲能領域的智能之選

一、產品簡介 ADL3000-E/C是安科瑞針對電力系統、工礦企業、公用設施的電力監控及能耗統計、管理需求而精心設計的一款智能儀表。該電能表具有精度高、體積小、安裝方便等顯著優點&#xff0c;為工商業儲能系統的智能化管理提供了強有力的技術支持。 功能特性 測量與計量功能…

條件向量運算與三元表達式

在工程計算和數學建模中&#xff0c;我們經常需要根據條件動態選擇不同的向量運算方式。這種需求在動力學系統、控制理論和計算機圖形學中尤為常見。本文將探討如何通過 Python 的三元表達式結合 SymPy 符號計算庫&#xff0c;實現條件向量運算的高效解決方案。 我們從定義兩…

文檔開發組件Aspose旗下熱門產品優勢及應用場景介紹

?Aspose 是什么&#xff1f; Aspose 是全球領先的文檔處理組件廠商&#xff0c;主打一個字&#xff1a;全。 &#x1f4cc; 支持超 100 種文檔/圖像格式 &#x1f4cc; 覆蓋 Word、Excel、PDF、PPT、OCR、BarCode、Email 等模塊 &#x1f4cc; 支持 .NET、Java、Python、C、N…

龍虎榜——20250618

上證指數縮量長下影小陽線&#xff0c;個股下跌超3300只&#xff0c;總體護盤的板塊表現相對更好。 深證指數縮量收小陽線&#xff0c;橫盤震蕩已有4天&#xff0c;等待方向選擇。 2025年6月18日龍虎榜行業方向分析 1. 半導體 代表標的&#xff1a;滬電股份&#xff08;高階P…

layui和vue父子級頁面及操作

最近在老項目里面添加一些頁面&#xff0c;項目太老只能在原有的項目基礎和插件上添加代碼 html //表格 <table id"dataTable"><thead><tr><th>序號</th><th>名稱</th><th></th></tr></th…

Houdini 節點使用方法

Houdini 的節點系統是其程序化建模和特效制作的核心功能之一&#xff0c;通過節點網絡實現程序化建模、特效制作、動力學模擬等復雜任務。掌握節點使用方法是高效創作的關鍵&#xff0c;以下是圍繞用戶需求的 全面、深入且結構化 的節點使用指南 一、節點基礎操作 1. 創建與連…

license授權文件說明

license管理 1.使用場景 系統將自動檢測license信息是否過期 - license過去前一個月&#xff0c;會顯示warning&#xff1a;license file will expire in 30 days - 當license過去&#xff0c;會顯示license file expired#注意 1. 數據庫重啟時才會啟動 License 授權期限校驗…

C++11中alignof和alignas的入門到精通指南

文章目錄 一、引言二、內存對齊的概念和作用2.1 什么是內存對齊2.2 內存對齊的優勢 三、alignof運算符3.1 定義和作用3.2 語法規則3.3 使用示例3.4 注意事項 四、alignas說明符4.1 定義和作用4.2 語法規則4.3 使用示例4.4 注意事項 五、alignof和alignas的結合使用六、實際應用…

防爆+高性能!ABB 防爆伺服電機HY系列守護安全生產

在石油、化工、火工等高風險行業中&#xff0c;如何在易燃易爆環境中確保設備安全穩定運行&#xff0c;同時兼顧高性能&#xff1f;ABB防爆伺服電機HY系列給出了完美答案&#xff01; 專為爆炸性環境設計&#xff0c;安全與性能兼得 ABB HY系列基于先進的HDS伺服平臺打造&…

洪千武—華為海外HRBP

我的個人介紹 辰熙咨詢創始人&CEO 2005年入職華為人力資源管理部 華為海外首批HRBP推動者、華為TUP股權激勵實戰顧問 華為IBM項目組成員、華為海外代表處AT成員 著有《OKR管理法則》、《力出一孔》 2005年以HR英文專才&#xff0c;從香港著名咨詢公司被獵聘到華為人力…

測試:網絡協議超級詳解

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】 【測試經驗】 【人工智能】 【Python】 </

游戲技能編輯器界面優化設計

界面布局重構 詳細界面布局 ---------------------------------------------------------- | 頂部工具欄 [保存] [加載] [撤銷] [重做] [測試] [設置] | --------------------------------------------------------- | 資源管理 | | 屬性編…

【java中使用stream處理list數據提取其中的某個字段,并由List<String>轉為List<Long>】

你當前的代碼是這樣的&#xff1a; List<String> gongkuangIds gongkuangBoundList.stream().filter(obj -> obj.getBoundValue() ! null).map(PlanSchemeProductionBoundInfo::getBoundValue).distinct().collect(Collectors.toList());這段代碼從 gongkuangBoundL…

《前端面試題:JS數組去重》

JavaScript數組去重終極指南&#xff1a;從基礎到高級的多種方法&#xff08;附面試題解析&#xff09; 在前端開發中&#xff0c;數組去重是JavaScript中最常見的需求之一。本文將全面解析8種數組去重方法&#xff0c;包括基礎實現、ES6新特性、性能優化等&#xff0c;并附上…

基于51單片機的智能小車:按鍵調速、障礙跟蹤、紅外循跡與數碼管顯示(一個合格的單片機課設)

引言 在嵌入式系統領域&#xff0c;51單片機因其簡單易用、成本低廉的特點&#xff0c;一直是入門學習的理想平臺。今天我將分享一個基于51單片機的多功能智能小車項目&#xff0c;它集成了按鍵PWM調速、障礙物跟蹤、紅外循跡和數碼管顯示四大功能。這個項目不僅涵蓋了嵌入式開…

Java異常處理(try-catch-finally):像醫生一樣處理程序的“感冒”

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 一、從一個真實問題開始&#xff1a;為什么需要異常處理&#xff1f; 假設你正在開發一個文件讀取工具&#xff0c;用戶輸入文件名后&#xff0c;程序會讀…

PostgreSQL 數據庫故障與性能高效實時監測技術深度解析

關鍵詞&#xff1a; postgresql 故障與性能監控 &#x1f4d1; 文章目錄 1. 引言與監控重要性 2. PostgreSQL監控體系架構 3. 故障監控核心技術 4. 性能監控關鍵指標 5. 實時監測技術實現 6. 監控工具選型與部署 7. 故障預警與自動化響應 8. 性能調優監控策略 9. 最佳…