wordpress 顯示字體大小seo排名分析
一、線程的概念
1.1 什么是線程
- 在一個程序里的一個執(zhí)行路線就叫做線程,更準(zhǔn)確的定義是:線程是“一個進程內(nèi)部的控制序列”
- 一切進程至少都有一個執(zhí)行線程
- 線程在進程內(nèi)部運行,本質(zhì)是在進程地址空間內(nèi)運行
- 在Linux系統(tǒng)中,在CPU眼中,看到的PCB都要比傳統(tǒng)的進程更加輕量化
- 透過進程虛擬地址空間,可以看到進程的大部分資源,將進程資源合理分配給每一個執(zhí)行流,就形成了線程執(zhí)行流
- 線程是進程內(nèi)部的一個執(zhí)行分支,線程是CPU調(diào)度的基本單位
- 加載到內(nèi)存中的程序叫做進程,進程 = 內(nèi)核數(shù)據(jù)結(jié)構(gòu) + 進程代碼和數(shù)據(jù)
???????我們在正文代碼區(qū)中,全部都是串行調(diào)用的,在地址空間和地址空間上的虛擬地址本質(zhì)上是一種資源,當(dāng)我們在創(chuàng)建進程的時候,需要創(chuàng)建虛擬地址空間,頁表,進程PCB等,需要時間和空間,比較麻煩。
???????????????在Windows中,操作系統(tǒng)會創(chuàng)建線程控制塊,因為線程的數(shù)量很多,所以需要先描述,在組織。有一個缺點是非常復(fù)雜。所以Linux的設(shè)計者認(rèn)為進程和線程都是執(zhí)行流,具有極度的相似性,沒有必要單獨設(shè)計出數(shù)據(jù)結(jié)構(gòu)和算法,直接服用代碼即可,使用進程來模擬線程。
????????
1.2 線程的優(yōu)點和缺點
1.2.1 線程的優(yōu)點
- 創(chuàng)建一個新線程的代價要比創(chuàng)建一個新進程小得多
- 與進程之間的切換相比,線程之間的切換需要操作系統(tǒng)做的工作要少的很多
- 線程占用的資源要比進程少很多
- 能充分利用多處理器的可并行數(shù)量,但是線程的數(shù)量最好不要超過CPU的核數(shù)
- 在等待慢速I/O操作結(jié)束的同時,程序可執(zhí)行其他的計算任務(wù)
- 計算密集型應(yīng)用,為了能在多處理器系統(tǒng)上運行,將計算分解到多個線程中實現(xiàn)
- I/O密集型應(yīng)用,為了提高性能,將I/O操作重疊,線程可以同時等待不同的I/O操作
1.2.2 線程的缺點
- 性能損失:一個很少被外部事件阻塞的計算密集型線程往往無法與其他線程共享同一個處理器。如果計算密集型線程的數(shù)量比可用的處理器多,那么可能會有較大的性能損失,這里的性能損失指的是增加了額外的同步和調(diào)度開銷,但是可用的資源是不變的
- 健壯性降低:編寫多線程需要更全面更深入的考慮,在一個多線程程序中,因時間分配上的細(xì)微偏差或者因為共享了不該共享的變量而造成不良影響的可能性是很大的,換句話說線程之間是缺乏保護的
- 缺乏訪問控制:進程是訪問控制的基本粒度,在一個線程中調(diào)用某些OS函數(shù)會對整個進程造成影響
- 編程難度的提高:編寫和調(diào)試一個多線程程序比單線程程序困難的多
1.3 線程的異常
- 單個線程如果出現(xiàn)了除零,野指針的問題會導(dǎo)致線程崩潰,進程也會隨著崩潰
- 線程是進程的執(zhí)行分支,線程出現(xiàn)異常,就類似于進程出現(xiàn)異常,進而觸發(fā)信號機制,終止進程,進程一旦終止,該進程內(nèi)的所有線程也就隨機退出了
1.4 線程的用途
- 合理的使用多線程,能提高CPU密集型程序的執(zhí)行效率
- 合理的使用多線程,能提高IO密集型程序的用戶體驗
二、Linux進程 VS 線程
???????在以前的進程的理解中,一個進程內(nèi)部只有一個線程的進程,但是在線程中,一個進程中至少有一個線程,線程是執(zhí)行流。
???????那么進程是什么呢?進程的內(nèi)核角度上,進程是承擔(dān)分配系統(tǒng)資源的基本實體。我們不要站在調(diào)度的角度區(qū)理解進程,而是應(yīng)該站在資源的角度理解進程。
關(guān)于調(diào)度,我們來談一談進程調(diào)度和線程調(diào)度都是什么?
???????在進程中,我們來進行CPU調(diào)度是需要重新加載進程的上下文數(shù)據(jù)和一個數(shù)據(jù)結(jié)構(gòu),但是在線程中,CPU調(diào)度只需要重新加載進程的PCB即可,那么進程調(diào)度也就比線程調(diào)度需要多加載幾個數(shù)據(jù)結(jié)構(gòu),速度也沒有慢到哪里。
那么究竟是什么讓線程調(diào)度優(yōu)于進程調(diào)度呢??
???????CPU中有一個硬件叫做cache,也叫做緩存,有一個東西叫做時間相關(guān)性和空間相關(guān)性,當(dāng)CPU去執(zhí)行代碼時,會將代碼拷貝到緩存中,并且會將該行代碼下面的部分代碼也拷貝到緩存中,所以,當(dāng)我們進行進程調(diào)度的時候,我們會發(fā)現(xiàn)原先拷貝到緩存中的代碼不能使用,因此需要我們重新去拷貝代碼;但是在進行線程調(diào)度的時候,我們不需要進行將緩存中的代碼進行替換,因為線程是共享代碼區(qū)的。
進程和線程的概念以及線程的共享區(qū)和私有區(qū)
- 進程是資源分配的基本單位
- 線程是調(diào)度的基本單位
線程共享進程數(shù)據(jù),但是也擁有自己的一部分?jǐn)?shù)據(jù):
- 線程ID
- 一組寄存器
- 棧
- errno
- 信號屏蔽字
- 調(diào)度優(yōu)先級
- 進程的多個線程共享
????????同一個地址空間,因此Text Segment,Data?Text Segment 都是共享的,如果定義一個函數(shù),在各個線程中都可以調(diào)用,如果定義個全局變量,在各個線程中都可以訪問到,各個線程還共享以下進程資源和環(huán)境:
- 文件描述符
- 每一種信號的處理方式(SIG_ IGN、SIG_ DFL或者自定義的信號處理函數(shù))
- 當(dāng)前工作目錄
- 用戶ID和組ID
進程和線程的關(guān)系如下圖:
三、再談地址空間
???????我們一般來說,多個線程是共享的,多個線程就是多個執(zhí)行流,這個多個執(zhí)行流可以將共享的代碼進行劃分,那么如何進行劃分多個執(zhí)行流呢??
???????在之前,我們談及了頁表,那么我們現(xiàn)在還計算一下頁表占用的空間大小,在2^32位的地址空間中,由于每一個地址空間需要進行虛擬地址到物理地址空間的轉(zhuǎn)換,所以一共需要2^32個地址轉(zhuǎn)換,在頁表中,一行上具有虛擬地址空間(4字節(jié)),物理地址空間(4字節(jié)),一些屬性,就按一行10個字節(jié)來計算,但屬性肯定不會這么少,那么一共需要:2^32 * 10 字節(jié)的空間,換算一下是40GB的地址空間,內(nèi)存才4GB,一個頁表居然需要40GB的地址空間,肯定不現(xiàn)實啊!所以實際上的頁表不是這么存儲的。
???????在談?wù)擁摫碇?#xff0c;我們需要先來看一看內(nèi)存在操作系統(tǒng)中的結(jié)構(gòu)是什么?
???????內(nèi)存也有結(jié)構(gòu)嗎?內(nèi)存在操作系統(tǒng)中不是直接的一整個大的空間,而是由一份一份小的空間來進行操作的,在文件系統(tǒng)中,在磁盤存儲中,文件是有屬性的,以4KB為基本數(shù)據(jù)單元,而在內(nèi)存中的基本數(shù)據(jù)單位也是4KB,那么一個4GB的內(nèi)存有1048576個4KB個數(shù)據(jù)單元,所以操作系統(tǒng)需要先描述,在組織,有屬于他的結(jié)構(gòu)體:struct page,有一個屬性是flag,我們可以將這個內(nèi)存是不是內(nèi)核的,還是用戶的,是不是已經(jīng)被使用了等等的屬性用宏去定義,在flag中聲明。
???????那么頁表在操作系統(tǒng)應(yīng)該是怎樣的結(jié)構(gòu)呢?我們可以將虛擬地址進行劃分為三個部分,一共是32比特,一部分是10比特,一部分是10比特,一部分是12比特,劃分結(jié)果為下圖所示: