Linux:線程控制

線程概念

線程(Thread)是進程(Process)?中的一個執行單元,是操作系統能夠進行運算調度的最小單位。

線程也被稱為“輕量級進程”(Lightweight Process, LWP)。

一個進程可以包含多個線程,這些線程共享該進程所擁有的全部資源(后續展開解釋)。

輕量級進程

為什么認為線程是輕量級進程,主要有兩方面:

1.線程創建:創建線程不產生新的進程地址空間,也就不需要創建對應的頁表

2.線程切換:

(1)由于進程地址空間不同,進程切換時無法從高速緩存中讀取數據,只能從較慢的內存中讀取數據,而線程由于共享地址空間,更有可能直接從緩存中讀取數據。

(2)由于進程地址空間不同,進程切換時會導致TLB失效,不能直接通過較快的TLB獲得物理地址,而是需要通過較慢的頁表來獲得物理地址,而進程由于共享地址空間,即使在緩存中讀取不到數據,也更有可能通過高速的TLB來獲得物理地址進而訪問內存

(3)相較于進程切換,線程切換時需要保存和恢復上下文更少

Linux下的線程

Linux下并沒有為線程設計獨立的概念和數據結構(即沒有與PCB相對的TCB),線程和進程都是通過task_strcut來進行管理和調度的,線程和進程也都是通過同一個底層系統調用?clone()?來創建的。

不過為了內核對線程進行調度,線程有用于標識自身唯一性的ID:LWP(類型為pid_t)

使用命令ps -aL可以看到線程ID:

使用函數gettid()也可以獲取線程ID:

線程資源共享

1.cpu分配給進程的時間片會均分給每一個線程

2.每個線程都有和進程一樣的虛擬地址空間(這意味著理論上線程可以訪問進程所有的代碼和數據)。

3.此外,線程還共享?件描述符表 ,每種信號的處理?式,當前?作?錄 ,??id和組id。

線程獨立

線程之間共享進程的所有資源,但為了各自完成不同的任務,還需要使得線程之間在一定程度上相互獨立,這就需要每個線程持有一部分私有內容來標識自身唯一性并獨立完成任務。

因此,每個線程擁有獨立的:

線程ID,用于標識自身唯一性

信號掩碼

調度策略和優先級

錯誤碼

線程執行上下文,包括:

????????程序計數器 (Program Counter): 指示當前執行指令的位置。

????????寄存器集合 (Register Set): 存儲線程運行時的臨時數據。

線程棧 (Stack): 用于存儲函數調用時的局部變量、參數、返回地址等。每個線程的棧是私有的,這是保證線程獨立執行的關鍵。

線程局部存儲(TLS):用于存儲只能被該線程訪問的全局變量

維護線程獨立

pthread庫通過數據結構struct_pthread來維護線程獨立,struct_pthread位于共享區

而線程id就是該線程對應的struct_pthread的首地址(該線程id用于調用其他的線程API,屬于進程級,并不是內核級的、用于標識線程唯一性的線程id),類型為pthread_t

線程棧

進程在創建時會復制父進程的棧區的地址空間,在使用時可以進行寫時拷貝和動態增長?。

但由主線程?成的?線程,它的棧將不再是向下??的,?是事先在共享區占用一個固定大小的空間。

線程局部存儲

在進程內的全局變量被所有線程共享,有時我們希望一個全局變量被每個線程持有一個副本,這時就需要__thread來修飾該變量,此時該全局變量被每個線程獨立地訪問和操作

但是要注意:__thread只能用來修飾內置類型,不能用來修飾自定義類型。

編寫如下代碼進行測試:

?#include<pthread.h>
#include<unistd.h>
#include<iostream>__thread int v=100;void* task(void* arg)
{v+=(long long)arg;std::cout<<"線程"<<gettid()<<"的v是"<<v<<std::endl;return 0;
}int main()
{pthread_t t1,t2;pthread_create(&t1,NULL,task,(void*)1);  pthread_create(&t2,NULL,task,(void*)2);pthread_join(t1,NULL);pthread_join(t2,NULL);
}

輸出結果:

可以看到兩個線程對全局變量的操作互不干擾

Linux線程控制

線程創建

thread:返回線程ID

attr:設置線程的屬性,attr為NULL表?使?默認屬性

start_routine:是個函數地址,線程啟動后要執?的函數

arg:傳給線程啟動函數的參數

返回值:成功返回0,失敗返回錯誤碼

線程終止

終止當前線程:

retval:用于輸出線程要執行的函數的返回值

終止指定線程:

返回值:成功返回0,失敗返回錯誤碼

終止某一線程的三種方法:

1.從線程函數return。這種?法對主線程不適?,從main函數return相當于調?exit。

2. 線程可以調?pthread_ exit終???。

3. ?個線程可以調?pthread_ cancel終?同?進程中的另?個線程。

線程等待

主線程等待指定線程結束

thread:用于指定線程

retval:用于傳出線程執行函數的返回值

線程分離

線程有兩種狀態:joinable和detached

默認情況下,新創建的線程是joinable的,線程退出后,需要主線程調用pthread_join,否則?法釋放資源,從?造成系統泄漏。

如果不關?線程的返回值,可以調用pthread_detach,當線程退出時,?動釋放線程資源。

適用于主線程為死循環的情景

thread:用于指定線程

注意:pthread_join和pthread_exit傳參時不要傳局部變量給retval,因為線程返回的值必須在線程結束后仍然有效。

多線程優缺點

優點:

1.創建與切換開銷低
2.在等待慢速I/O操作結束的同時,程序可執行其他的計算任務
3.對于計算密集型應用,為了能在多處理系統上運行,將計算分解到多個線程中實現
4.對于I/O 密集型應用,為了提高性能,將I/O操作重疊。線程可以同時等待不同的I/O操作。

缺點:
1.性能損失
一個很少被外部事件阻塞的計算密集型線程往往無法與其他線程共享同一個處理器。如果計算密集型線程的數量比可用的處理器多,那么可能會有額外的同步和調度開銷。
2.健壯性降低
線程共享數據容易引發線程安全問題。
單個線程如果出現除零,野指針問題導致線程崩潰,進程也會隨之崩潰。
3.缺乏訪問控制
進程是訪問控制的基本粒度,在一個線程中調用某些OS函數會對整個進程造成影響。
4.編程難度提高
編寫與調試一個多線程程序比單線程程序困難得多??

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

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

相關文章

React 學習(4)

核心API———createRoot、render方法1.createRoot 方法是創建react的根容器&#xff0c;就是react元素的插入位置&#xff0c;插入的dom會被轉化成react元素&#xff0c;根容器內的內容都會被react管理&#xff0c;原有dom都會被刪除。react17 根容器創建、渲染方式&#xff0…

ASP .NET Core 8集成Swagger全攻略

Swagger (現在稱為 OpenAPI) 是一個用于描述 RESTful API 的規范&#xff0c;ASP.NET Core 內置支持通過 Swashbuckle 庫生成 Swagger 文檔。以下是在 ASP.NET Core 8 中實現 Swagger 的完整步驟。1、添加Swagger NuGet 包dotnet add package Swashbuckle.AspNetCore2、添加Swa…

【iOS】源碼閱讀(六)——方法交換

文章目錄方法交換什么是Method-Swizzling方法交換核心API**1. 獲取方法對象****2. 添加/替換方法實現****3. 交換方法實現****4. 獲取方法信息****5. 修改方法實現****使用示例&#xff1a;完整的 Method-Swizzling 流程****注意事項**使用方法交換注意事項線程安全方法交換的影…

mysql運維問題解決:MySQL主從延遲(鎖阻塞與讀寫分離)

小亦平臺會持續給大家科普一些運維過程中常見的問題解決案例&#xff0c;運維朋友們可以在常見問題及解決方案專欄查看更多案例 問題概述 告警事件&#xff1a; 2023-07-28 03:31:39.571 首次觸發主從延遲告警&#xff08;延遲1515秒&#xff09;2023-07-28 07:41:37 告警解除…

SSH 密鑰

什么是 SSH 密鑰 SSH 密鑰就像是你電腦的“身份證”和“鑰匙”&#xff0c; 用來安全登錄另一臺電腦&#xff08;服務器&#xff09;&#xff0c;而不需要每次輸入密碼。SSH 密鑰是一種安全登錄遠程服務器的方式&#xff0c;由一對加密的“鑰匙”組成&#xff1a;一個公鑰 一個…

st-Gcn訓練跳繩識別模型一:數據標注工具和標注流程

目錄 工具展示和使用說明 工具標注后文件展示說明 json轉換成單個npy文件 數據獲取補充 工具展示和使用說明 文件名labelV.py集于PySide6實現&#xff1a; 通過選擇視頻來選擇你要標注的視頻&#xff0c;然后選擇保存路徑&#xff1a; 然后視頻兩個類別。當你看見視頻中的人…

springboot跨域問題 和 401

springboot跨域問題 和 401 1.跨域import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotatio…

構建直播平臺大體的流程

? 直播流程完整鏈路&#xff08;基于 SRS OBS 前后端&#xff09;&#x1f9cd;?♂? 用戶操作流程&#xff1a;? 用戶登錄系統&#xff08;前端&#xff09;系統中校驗用戶身份&#xff08;JWT 等&#xff09;后端可能校驗權限&#xff0c;比如“是否有開播資格”? 用戶…

KOSMOS-2: 將多模態大型語言模型與世界對接

溫馨提示&#xff1a; 本篇文章已同步至"AI專題精講" KOSMOS-2: 將多模態大型語言模型與世界對接 摘要 我們介紹了 KOSMOS-2&#xff0c;一種多模態大型語言模型&#xff08;MLLM&#xff09;&#xff0c;賦予了模型感知物體描述&#xff08;例如&#xff0c;邊界框…

協作機器人操作與編程-PE系統示教編程和腳本講解(直播回放)

協作機器人操作與編程-PE系統示教編程和腳本講解本次講解主要圍繞協作機器人PE系統的操作與編程展開&#xff0c;內容涵蓋軟件安裝、虛擬機配置、手動操作、在線編程、變量設置、網絡通信及標定方法等方面。以下是主要內容要點提煉&#xff1a; 軟件安裝與虛擬機配置 需從官網下…

【前后端】Node.js 模塊大全

用到的全部總結在這里&#xff0c;不定期更新 鏈接 node一本通 包括&#xff1a; express path fs/ process/ os/ http/ mysql/mongoose/ express-jwt/jsonwebtoken/ dotenv/ multer/ swagger/ cors/ nodemon (docker篇有)常用模塊 內置 fs 文件系統操作&#xff08;讀寫、重命…

雙8無碳小車“cad【17張】三維圖+設計說名書

基于MATLAB的雙八無碳小車軌跡仿真及其結構設計 摘 要 本文設計的基于MATLAB的無碳小車來自于全國大學生工程訓練能力競賽&#xff0c;依據綠色環保&#xff0c;設計一種通過重力勢能轉換成動能來驅動小車行走的裝置。通過分析任務要求&#xff0c;本文完成了小車的三維結構設計…

視覺大模型離線部署全流程優化:從微調技術到工程實踐

視覺大模型離線部署全流程優化&#xff1a;從微調技術到工程實踐 一、視覺大模型離線部署概述 1.1 視覺大模型的應用場景與挑戰 視覺大模型在物體檢測、圖像生成、圖像描述等領域展現出強大能力&#xff0c;已成為人工智能領域的研究熱點和產業應用焦點(5)。隨著技術的發…

Vue中組件的生命周期

組件的生命周期生命周期、生命周期函數、生命周期鉤子vue2的生命周期創建&#xff08;創建前的生命周期函數 beforeCreate &#xff0c;創建完畢created&#xff09;掛載&#xff08;掛載前beforeMount&#xff0c;掛載完畢mounted&#xff09;//把組件放在頁面中更新&#xff…

securecrt連接服務器報錯 Key exchange failed 怎么辦

新買了一臺阿里云機&#xff0c;用securecrt去連接&#xff0c;如下報錯這個錯誤表明你的 SSH 客戶端與服務器之間無法就密鑰交換方法和主機密鑰算法達成一致&#xff0c;導致連接失敗。這通常是由于客戶端和服務器支持的加密算法集不匹配造成的。 解決方式 編輯服務器的/etc/s…

用協議分層模型實戰:從物理層到應用層的STM32協議棧開發

目錄 1. 揭開協議棧的神秘面紗:從STM32到分層思維 STM32的硬件優勢 本章實戰:點亮物理層的第一步 2. 數據鏈路層:讓STM32學會“打包”和“拆包” 以太網幀的那些事兒 實戰:解析以太網幀 3. 網絡層:讓STM32學會“找路” LwIP的快速上手 實戰:實現一個簡單的Ping …

微服務基礎環境搭建-centos7

文章目錄1、安裝docker1.1、安裝步驟1.2、docker常用命令2、安裝Nginx3、Docker安裝Mysql4、Docker安裝Redis5、安裝Nacos5.1、Nacos的作用5.2、單體服務安裝6、安裝RocketMQ服務6.1 MQ的作用6.2 RocketMQ的基礎服務架構6.2、安裝RocketMQ服務6.3、安裝dashboard面板服務6.4、R…

Netty知識點

一、Netty的零拷貝機制 零拷貝的基本理念&#xff1a;避免在用戶態和內核態之間拷貝數據&#xff0c;從而降低 CPU 占用和內存帶寬的消耗除了系統層面的零拷貝。 1、FileRegion 接口 FileRegion 是 Netty 提供的用于文件傳輸的接口&#xff0c;它通過調用操作系統的 sendfile 函…

Kafka的基本使用

目錄 認識Kafka 消息隊列 消息隊列的核心概念 核心價值與解決的問題 Kafka ZooKeeper Kafka的基本使用 環境安裝 啟動zookeeper 啟動Kafka 消息主題 創建主題 查詢主題 修改主題 發送數據 命令行操作 JavaAPI操作 消費數據 命令行操作 JavaAPI操作 認識Kafka…

Flink2.0學習筆記:Table API SQL

stevensu1/EC0720 表 API 和 SQL# 表 API 和 SQL——用于統一流和批處理 加工。表 API 是適用于 Java、Scala 和 Python 的語言集成查詢 API&#xff0c;它 允許組合來自關系運算符的查詢&#xff0c;例如 selection、filter 和 join in 一種非常直觀的方式。Flink 的 SQL 支…