1昙读、簡(jiǎn)述進(jìn)程和線程
進(jìn)程:
1)操作系統(tǒng)進(jìn)行資源分配(內(nèi)存、磁盤(pán)竭讳、顯卡)的基本單位创葡,多個(gè)進(jìn)程之間相互獨(dú)立(地址空間和數(shù)據(jù)空間),需要通信的話是在操作系統(tǒng)層面進(jìn)行通信
2)穩(wěn)定性好代咸,如果一個(gè)進(jìn)程崩潰蹈丸,不影響其他進(jìn)程,但是進(jìn)程消耗資源大呐芥,開(kāi)啟的進(jìn)程數(shù)量有限制
線程:
1)CPU進(jìn)行資源分配和調(diào)度的基本單位(CPU看到的都是線程不是進(jìn)程)逻杖,線程是進(jìn)程的一部分,是比進(jìn)程更小的能夠獨(dú)立運(yùn)行的基本單位思瘟,一個(gè)進(jìn)程下的多個(gè)線程可以共享該進(jìn)程的所有資源(地址空間和數(shù)據(jù)空間)荸百,一個(gè)線程的數(shù)據(jù)可以直接提供給其他線程使用,比較方便滨攻,但同時(shí)會(huì)造成變量值的混亂够话,所以需要通過(guò)線程鎖來(lái)限制線程的執(zhí)行
2)如果IO操作密集蓝翰,則可以多線程運(yùn)行效率高,缺點(diǎn)就是如果一個(gè)線程崩潰女嘲,就會(huì)造成進(jìn)程的崩潰
應(yīng)用場(chǎng)景:
1)IO密集的用多線程畜份,在用戶輸入,sleep的時(shí)候欣尼,可以切換到其他線程執(zhí)行爆雹,減少等待的時(shí)間
2)CPU密集的用多進(jìn)程,因?yàn)榧偃鏘O操作較少愕鼓,用多線程的話钙态,因?yàn)榫€程共享一個(gè)全局解釋器鎖,當(dāng)前運(yùn)行的線程會(huì)霸占GIL菇晃,導(dǎo)致其他線程沒(méi)有GIL册倒,就不能充分利用多核CPU的優(yōu)勢(shì)
2、CPU密集型和IO密集型
CPU密集型:
指的是大部分的狀況下是CPU Loading 100%磺送,CPU要讀寫(xiě)I/O(硬盤(pán)/內(nèi)存)驻子,I/O在很短的時(shí)間內(nèi)就可以完成,而CPU還有很多運(yùn)算要處理估灿,整個(gè)過(guò)程中系統(tǒng)的硬盤(pán)拴孤、內(nèi)存性能相對(duì)CPU要好很多
例如:算法里面的模型運(yùn)算工作,如一個(gè)計(jì)算圓周率至小數(shù)點(diǎn)一千位以下的程序甲捏,在執(zhí)行的過(guò)程當(dāng)中絕大部份時(shí)間用在三角函數(shù)和開(kāi)根號(hào)的計(jì)算演熟,屬于CPU密集型的程序,全靠CPU的運(yùn)算能力司顿。這種計(jì)算密集型任務(wù)雖然可以用多線程完成芒粹,但是線程越多,花在線程切換的時(shí)間就越多大溜,CPU執(zhí)行任務(wù)的效率就越低化漆,所以,要高效地利用CPU钦奋,CPU密集型任務(wù)同時(shí)運(yùn)行的線程數(shù)量應(yīng)當(dāng)?shù)扔贑PU的核數(shù)座云,這樣可以占滿CPU資源,進(jìn)而充分利用CPU
IO密集型:
指的是大部分的狀況下是CPU在等I/O(硬盤(pán)/內(nèi)存)的讀寫(xiě)操作付材,此時(shí)的CPU Loading并不高朦拖,整個(gè)過(guò)程中系統(tǒng)的CPU性能相對(duì)硬盤(pán)、內(nèi)存要好很多
例如:讀寫(xiě)數(shù)據(jù)庫(kù)等厌衔,CPU消耗很少璧帝,任務(wù)的大部分時(shí)間都在等待IO操作完成(因?yàn)镮O的速度遠(yuǎn)遠(yuǎn)低于CPU和內(nèi)存的速度),對(duì)于IO密集型任務(wù)富寿,線程越多睬隶,CPU效率越高锣夹,但也要有一個(gè)限度,常見(jiàn)的大部分任務(wù)都是IO密集型任務(wù)
IO密集型任務(wù)執(zhí)行期間苏潜,99%的時(shí)間都花在IO上银萍,花在CPU上的時(shí)間很少,因?yàn)樾糇螅眠\(yùn)行速度極快的C語(yǔ)言替換Python這樣運(yùn)行速度極低的腳本語(yǔ)言砖顷,完全無(wú)法提升運(yùn)行效率,對(duì)于IO密集型任務(wù)赃梧,最合適的語(yǔ)言就是開(kāi)發(fā)效率高(代碼量少)的語(yǔ)言,腳本語(yǔ)言是首選豌熄,C語(yǔ)言最差
IO密集型任務(wù)線程由于等待IO會(huì)被阻塞授嘀,如果仍然使用等于 CPU核數(shù) 個(gè)線程,CPU是跑不滿的锣险,需要使用更多線程來(lái)提高CPU利用率
總之蹄皱,CPU密集型程序適合C語(yǔ)言多線程,IO密集型的適合腳本語(yǔ)言開(kāi)發(fā)的多線程
3芯肤、多核巷折、多進(jìn)程、多線程
計(jì)算機(jī)的物理核數(shù)是同時(shí)可以并行的線程數(shù)量(CPU看到的都是線程崖咨,線程是CPU調(diào)度分配的最小單位)锻拘,由于超線程技術(shù)(一個(gè)實(shí)體CPU提供兩個(gè)邏輯線程),實(shí)際上可以并行的線程數(shù)量通常是物理核數(shù)的兩倍击蹲,這也是操作系統(tǒng)看到的核數(shù)署拟,所以我們說(shuō)的核數(shù)是操作系統(tǒng)看到的核數(shù),指的是超線程技術(shù)之后的那個(gè)核(不是物理核)
如果計(jì)算機(jī)有多個(gè)CPU核歌豺,且計(jì)算機(jī)中總的線程數(shù)量小于核數(shù)推穷,那線程可以運(yùn)行在不同的核中。
如果是單核多線程类咧,那么多線程之間就不是并行馒铃,而是并發(fā),即為了負(fù)載均衡CPU調(diào)度器會(huì)不斷在單核上切換不同的線程執(zhí)行痕惋,但是我們說(shuō)過(guò)区宇,一個(gè)核只能運(yùn)行一個(gè)線程,所以并發(fā)雖然讓我們看起來(lái)不同線程之間的任務(wù)是并行執(zhí)行的值戳,但實(shí)際上因?yàn)樵黾恿司€程切換的開(kāi)銷使得代價(jià)更大了萧锉。
如果是多核多線程,且線程數(shù)量大于核數(shù)述寡,其中有些線程就會(huì)不斷切換柿隙,并發(fā)執(zhí)行叶洞,但實(shí)際上最大的并行數(shù)量還是CPU的核的數(shù)量。
4禀崖、linux中最大進(jìn)程數(shù)衩辟、最大線程數(shù)
最大進(jìn)程數(shù)
(1)32位系統(tǒng)中最多可以起32768個(gè)進(jìn)程
(2)64位系統(tǒng)中最多可以起2的22次方(4194304)約420萬(wàn)個(gè)
[root@**** ~]$ cat /proc/sys/kernel/pid_max
32768
最大線程數(shù)
其實(shí)最大線程數(shù)量也可以配置無(wú)限大,在資源充足的情況下波附,但一般都有會(huì)默認(rèn)限制
[root@**** ~]$ cat /proc/sys/kernel/threads-max
1543275
正常情況下艺晴,系統(tǒng)默認(rèn)的配置已經(jīng)足夠我們使用,除非想進(jìn)行一些極限性能測(cè)試或者性能優(yōu)化掸屡,這時(shí)候可以根據(jù)具體的情況來(lái)調(diào)整上面提到的幾個(gè)參數(shù)
5封寞、python語(yǔ)言特殊性
CPU是多核時(shí)支持多個(gè)線程同時(shí)執(zhí)行,但在python中仅财,無(wú)論是單核還是多核狈究,一個(gè)進(jìn)程同時(shí)只能由一個(gè)線程在執(zhí)行。根源在于GIL的存在盏求,GIL全稱是Global Interpreter Lock(全局解釋鎖)抖锥,來(lái)源是python設(shè)計(jì)之初的考慮,為了數(shù)據(jù)安全所做的決定碎罚,某個(gè)線程想要執(zhí)行磅废,必須先拿到 GIL,我們可以把 GIL 看作是“通行證”荆烈,并且在一個(gè) Python 進(jìn)程中拯勉,GIL 只有一個(gè),拿不到通行證的線程憔购,就不允許進(jìn)入 CPU 執(zhí)行谜喊,所以多線程在python中很雞肋,多線程的運(yùn)行順序仍是有先后的倦始,并不是同時(shí)進(jìn)行的斗遏。