一文搞懂多線程中各個(gè)難點(diǎn)
1.什么是線程?
linux內(nèi)核中是沒(méi)有線程這個(gè)概念的,而是輕量級(jí)進(jìn)程的概念:LWP。一般我們所說(shuō)的線程概念是C庫(kù)當(dāng)中的概念。
1.1線程是怎樣描述的?
線程實(shí)際上也是一個(gè)task_struct,工作線程拷貝主線程的task_struct,然后共用主線程的mm_struct。線程ID是在用task_struct中pid描述的,而task_struct中tgid是線程組ID,表示線程屬于該線程組,對(duì)于主線程而言,其pid和tgid是相同的,我們一般看到的進(jìn)程ID就是tgid。
即:
獲取線程ID和主線程ID的值:
但是獲取該gettid系統(tǒng)調(diào)用接口并沒(méi)有被封裝起來(lái),如果確實(shí)需要獲取線程ID,可使用:
#include
則對(duì)線程組而言,所有的tgid一定是一樣的,所有的pid一定是不一樣的。主線程pid和tgid一樣,工作線程pid和tgid一定不一樣。
1.2如何查看一個(gè)線程的ID
命令:ps -eLf
上述polkitd進(jìn)程是多線程的,進(jìn)程ID為731,進(jìn)程內(nèi)有6個(gè)線程,線程ID為731,764,765,768,781,791。
1.3多線程如何避免調(diào)用;靵y的問(wèn)題?
工作線程和主線程共用一個(gè)mm_struct,如果都向棧中壓棧,必然會(huì)導(dǎo)致調(diào)用棧出錯(cuò)。
實(shí)際上工作線程壓棧是壓了共享區(qū),該共享區(qū)包含了許多線程獨(dú)有的資源。如圖:
每一個(gè)線程,默認(rèn)在共享區(qū)中占有的空間為8M,可以使用ulimit -s修改。
進(jìn)程是資源分配的基本單位,線程是調(diào)度的基本單位。
1.3.1線程獨(dú)有資源
線程ID
一組寄存器
errno
信號(hào)屏蔽字
調(diào)度優(yōu)先級(jí)
1.3.2線程共享資源和環(huán)境
文件描述符表
信號(hào)的處理方式
當(dāng)前工作目錄
用戶id和組id
1.4為什么要有多線程?
舉個(gè)生活中的例子, 這就好比去銀行辦理業(yè)務(wù)。到達(dá)銀行后, 首先取一個(gè)號(hào)碼, 然后坐下來(lái)安心等待。這時(shí)候你一定希望, 辦理業(yè)務(wù)的窗口越多越好。如果把整個(gè)營(yíng)業(yè)大廳當(dāng)成一個(gè)進(jìn)程的話, 那么每一個(gè)窗口就是一個(gè)工作線程。
1.4.1線程帶來(lái)的優(yōu)勢(shì)
1、線程會(huì)共享內(nèi)存地址空間。
2、創(chuàng)建線程花費(fèi)的時(shí)間要少于創(chuàng)建進(jìn)程花費(fèi)的時(shí)間。
3、終止線程花費(fèi)的時(shí)間要少于終止進(jìn)程花費(fèi)的時(shí)間。
4、線程之間上下文切換的開銷, 要小于進(jìn)程之間的上下文切換。
5、線程之間數(shù)據(jù)的共享比進(jìn)程之間的共享要簡(jiǎn)單。
6、充分利用多處理器的可并行數(shù)量。(線程會(huì)提高運(yùn)行效率,但當(dāng)線程多到一定程度后,可能會(huì)導(dǎo)致效率下降,因?yàn)闀?huì)有線程調(diào)度切換。)
1.4.2線程帶來(lái)的缺點(diǎn)
健壯性降低:多個(gè)線程之中, 只要有一個(gè)線程不夠健壯存在bug(如訪問(wèn)了非法地址引發(fā)的段錯(cuò)誤) , 就會(huì)導(dǎo)致進(jìn)程內(nèi)的所有線程一起完蛋。
線程模型作為一種并發(fā)的編程模型, 效率并沒(méi)有想象的那么高, 會(huì)出現(xiàn)復(fù)雜度高、 易出錯(cuò)、 難以測(cè)試和定位的問(wèn)題。
1.5注意
1、并不是只有主線程才能創(chuàng)建線程, 被創(chuàng)建出來(lái)的線程同樣可以創(chuàng)建線程。
2、不存在類似于fork函數(shù)那樣的父子關(guān)系, 大家都?xì)w屬于同一個(gè)線程組, 進(jìn)程ID都相等, group_leader都指向主線程, 而且各有各的線程ID。
通過(guò)group_leader指針, 每個(gè)線程都能找到主線程。主線程存在一個(gè)鏈表頭,后面創(chuàng)建的每一個(gè)線程都會(huì)鏈入到該雙向鏈表中。
3、并非只有主線程才能調(diào)用pthread_join連接其他線程, 同一線程組內(nèi)的任意線程都可以對(duì)某線程執(zhí)行pthread_join函數(shù)。
4、并非只有主線程才能調(diào)用pthread_detach函數(shù), 其實(shí)任意線程都可以對(duì)同一線程組內(nèi)的線程執(zhí)行分離操作。
線程的對(duì)等關(guān)系:
2.線程創(chuàng)建
接口:int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
參數(shù)解釋
1、thread:線程標(biāo)識(shí)符,是一個(gè)出參
2、attr:線程屬性
3、star_routine:函數(shù)指針,保存線程入口函數(shù)的地址
4、arg:給線程入口函數(shù)傳參
返回值:成功返回0,失敗返回error number
詳解:
第一個(gè)參數(shù)是pthread_t類型的指針, 線程創(chuàng)建成功的話,會(huì)將分配的線程ID填入該指針指向的地址。線程的后續(xù)操作將使用該值作為線程的唯一標(biāo)識(shí)。
第二個(gè)參數(shù)是pthread_attr_t類型, 通過(guò)該參數(shù)可以定制線程的屬性, 比如可以指定新建線程棧的大小、 調(diào)度策略等。如果創(chuàng)建線程無(wú)特殊的要求, 該值也可以是NULL, 表示采用默認(rèn)屬性。
第三個(gè)參數(shù)是線程需要執(zhí)行的函數(shù)。創(chuàng)建線程, 是為了讓線程執(zhí)行一定的任務(wù)。線程創(chuàng)建成功之后, 該線程就會(huì)執(zhí)行start_routine函數(shù), 該函數(shù)之于線程, 就如同main函數(shù)之于主線程。
第四個(gè)參數(shù)是新建線程執(zhí)行的start_routine函數(shù)的入?yún)ⅰ?/p>
pthread_create錯(cuò)誤碼及描述:
2.1傳入?yún)?shù)arg的選擇
不要使用臨時(shí)變量傳參,使用堆上開辟的變量可以。
例:
#include
線程獲取自身的ID:
#include
判斷兩個(gè)線程ID是否對(duì)應(yīng)著同一個(gè)線程:
#include
返回為0時(shí),則表示兩個(gè)線程為同一個(gè)線程,非0時(shí),表示不是同一個(gè)線程。
用戶調(diào)用pthread_create函數(shù)時(shí), 首先要為線程分配線程棧, 而線程棧的位置就落在共享區(qū)。調(diào)用mmap函數(shù)為線程分配?臻g。pthread_create函數(shù)分配的pthread_t類型的線程ID, 不過(guò)是分配出來(lái)的空間里的一個(gè)地址, 更確切地說(shuō)是一個(gè)結(jié)構(gòu)體的指針。
即:

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
3月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會(huì)
-
4月30日立即下載>> 【村田汽車】汽車E/E架構(gòu)革新中,新智能座艙挑戰(zhàn)的解決方案
-
5月15-17日立即預(yù)約>> 【線下巡回】2025年STM32峰會(huì)
-
即日-5.15立即報(bào)名>>> 【在線會(huì)議】安森美Hyperlux™ ID系列引領(lǐng)iToF技術(shù)革新
-
5月15日立即下載>> 【白皮書】精確和高效地表征3000V/20A功率器件應(yīng)用指南
-
5月16日立即參評(píng) >> 【評(píng)選啟動(dòng)】維科杯·OFweek 2025(第十屆)人工智能行業(yè)年度評(píng)選
推薦專題
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達(dá)AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀(jì)”爆發(fā)至今,五類新物種登上歷史舞臺(tái)
- 5 國(guó)產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計(jì)算迎來(lái)商業(yè)化突破,但落地仍需時(shí)間
- 7 東陽(yáng)光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長(zhǎng)空間
- 8 地平線自動(dòng)駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營(yíng)收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機(jī)器人東風(fēng)翻身?