進(jìn)程最近有些煩惱,整日愁眉苦臉的申尤,拜訪內(nèi)存的時(shí)候也有點(diǎn)心不在焉癌幕。
內(nèi)存是個(gè)明眼人,開門見山的問道:“進(jìn)程啊昧穿,最近遇到啥問題了勺远?我看你最近情緒有點(diǎn)低落,有啥問題你就直接說出來嘛粤咪,我讓大家伙兒來一起幫你想想辦法谚中。”
進(jìn)程嘆了口氣寥枝,說道:“唉宪塔,最近不是說 CPU 單核頻率到瓶頸了嗎?人類就用多核芯來彌補(bǔ)單核處理器性能的不足囊拜,咱們的 CPU 不也升級(jí)到四核了嘛某筐。”
“是啊冠跷,這是好事啊南誊,現(xiàn)在最多能并行處理 4 個(gè)進(jìn)程,效率比以前高多了蜜托,這還不好嗎抄囚?”內(nèi)存疑惑的問。
“好是好橄务,可我每次上 CPU 運(yùn)行的時(shí)候幔托,都忍不住去想,要是單核頻率不增加蜂挪,我總的運(yùn)行的時(shí)間不還是沒有什么變化嗎重挑?以后的應(yīng)用程序越來越大,越來越吃 CPU 資源棠涮,比如那些大型游戲進(jìn)程谬哀,在短時(shí)間內(nèi)需要進(jìn)行大量計(jì)算,靠單核撐不住怎么辦严肪。不談以后史煎,就說說我自己谦屑,我也想能夠早點(diǎn)運(yùn)行完,早點(diǎn)休息啊劲室÷兹裕”
tobe 注:很明顯單進(jìn)程的運(yùn)行時(shí)間是變小了的结窘,不過這里主要強(qiáng)調(diào)的是進(jìn)程占用 CPU 的時(shí)間很洋。
內(nèi)存點(diǎn)點(diǎn)頭,贊同道:“這個(gè)問題我倒是沒想到隧枫,多核處理器對單個(gè)進(jìn)程確實(shí)不大友好喉磁。那咱得想辦法讓你能夠同時(shí)使用幾個(gè)核心。不過我一時(shí)間也想不到什么好辦法官脓,還是和大家一起討論下吧协怒。”
在討論會(huì)上卑笨,內(nèi)存向大家說明了進(jìn)程現(xiàn)在遇到的問題孕暇。
“一個(gè)進(jìn)程怎么并行?”進(jìn)程調(diào)度器第一個(gè)發(fā)出疑問:“我總不能把一個(gè)進(jìn)程放在四個(gè)核上吧赤兴,這樣不僅毫無意義妖滔,還阻礙了其他進(jìn)程的執(zhí)行⊥傲迹”
操作系統(tǒng)見多識(shí)廣座舍,說:“把進(jìn)程一次放在幾個(gè)核上運(yùn)行肯定是不可能的,我在想陨帆,咱們的目標(biāo)曲秉,其實(shí)就是讓多個(gè)核心不沖突地幫助一個(gè)進(jìn)程運(yùn)行嘛。那我們就得把進(jìn)程「拆開」疲牵,然后放在幾個(gè)核上承二。”
操作系統(tǒng)一邊說纲爸,一邊畫了張圖:
“你們看亥鸠,假如說 fun1 和 fun2 這兩個(gè)函數(shù)互不關(guān)聯(lián),我們就可以讓兩個(gè)核同時(shí)執(zhí)行他們缩焦,這不就做到并行了嗎读虏?”
“你的意思是說把一個(gè)進(jìn)程拆成好幾個(gè)進(jìn)程?”
操作系統(tǒng)搖搖頭:“不是拆成多個(gè)進(jìn)程袁滥,進(jìn)程切換的代價(jià)太大了盖桥,再說了,這些拆出來的函數(shù)题翻,他們是共用一個(gè)地址空間的揩徊,天生就能夠數(shù)據(jù)共享腰鬼,如果拆成進(jìn)程,我們還得再考慮進(jìn)程之間的通信問題塑荒,那多麻煩熄赡。不過為了跟進(jìn)程區(qū)分,就叫他們「線程(Thread)」吧”
進(jìn)程一驚齿税,要把自己拆成線程彼硫?那自己不就沒了?趕忙問道:“那我豈不是沒有存在的余地了凌箕?”
進(jìn)程調(diào)度器也慌了:“要是沒了進(jìn)程拧篮,我是不是也要被退休了?”
操作系統(tǒng)趕忙解釋道:你們誤會(huì)了牵舱,我要拆開的串绩,是進(jìn)程的執(zhí)行流,進(jìn)程不是包含了資源所有權(quán)和執(zhí)行流嗎芜壁,資源所有權(quán)還是由進(jìn)程來把控礁凡,執(zhí)行流就分給幾個(gè)線程,就像這樣:
tobe 注:在進(jìn)程模型里慧妄,進(jìn)程擁有對內(nèi)存顷牌、I/O 通道、I/O 設(shè)備和文件等資源的控制權(quán)腰涧,稱之為「資源所有權(quán)」韧掩。「執(zhí)行流」可以看做進(jìn)程在 CPU 上的執(zhí)行過程(直觀一點(diǎn)就是高級(jí)語言里的語句)窖铡。
進(jìn)程恍然大悟:“也就是說我仍然是資源的掌控者疗锐,那些線程就相當(dāng)于幫我干活的小弟?”
“沒錯(cuò)费彼,而且從這種角度看滑臊,你本身還是一個(gè)單線程進(jìn)程」坎”
聽了這么久雇卷,內(nèi)存發(fā)問了:“創(chuàng)建進(jìn)程的時(shí)候,我要保存進(jìn)程 PCB 颠猴,那為了創(chuàng)建線程关划,我是不是還得創(chuàng)建一個(gè) TCB(Thread Control Block)?”
“當(dāng)然了翘瓮,線程切換需要的信息就得存在 TCB 里面贮折。不過你放心,TCB 要比 PCB 小得多资盅,所以線程切換會(huì)比進(jìn)程切換快很多调榄∮辉”
大家聽完,紛紛覺得「線程」這個(gè)模型完美的解決了當(dāng)前的問題每庆,說道:“要不我們現(xiàn)在就在操作系統(tǒng)里添上線程模型吧筐带,早點(diǎn)解決進(jìn)程的問題$土椋”
但是操作系統(tǒng)面露難色伦籍,說:“線程模型只是我們的一個(gè)假想,貿(mào)然加進(jìn)來的話凤价,可能會(huì)出問題鸽斟,系統(tǒng)崩潰可就不好了拔创,還是要以穩(wěn)定為主利诺。。剩燥。但這個(gè)模型還是得試的慢逾,要不我們先創(chuàng)建一個(gè)線程庫,靠一個(gè)用戶級(jí)別的應(yīng)用程序——線程調(diào)度器來管理這些線程吧灭红÷绿玻”
進(jìn)程不解的問:“可是這樣的話,我還是被分配在一個(gè)單獨(dú)的核心上啊变擒,即使是多線程君珠,也只能在單核上運(yùn)行。再說了娇斑,如果這些線程里有一個(gè)被阻塞策添,在你看來,是整個(gè)進(jìn)程阻塞了毫缆,那其他線程唯竹,即使是就緒態(tài),也得不到 CPU 資源苦丁〗牵”
操作系統(tǒng)仔細(xì)想了下,說:“沒辦法旺拉,用戶級(jí)線程確實(shí)有這兩個(gè)缺點(diǎn)产上,但相比起讓內(nèi)核來實(shí)現(xiàn)線程,用戶級(jí)線程也有他的好處——線程切換不需要我進(jìn)行狀態(tài)轉(zhuǎn)換(從用戶態(tài)到內(nèi)核態(tài))蛾狗,開銷小晋涣,除此之外,線程庫可以有多個(gè)調(diào)度算法淘太,能夠?yàn)閼?yīng)用程序量身定做調(diào)度算法姻僧」胬觯”
tobe 注:有一種解決線程阻塞的方案叫 jacketing,他可以把一個(gè)產(chǎn)生阻塞的系統(tǒng)調(diào)用轉(zhuǎn)化成一個(gè)非阻塞的系統(tǒng)調(diào)用撇贺,比如說赌莺,不直接調(diào)用系統(tǒng)級(jí)的 I/O 例程,而是讓線程調(diào)用應(yīng)用級(jí)的 I/O jacket 例程松嘶,這個(gè) jacket 例程會(huì)檢查 I/O 設(shè)備是否忙艘狭,如果忙的話,就不執(zhí)行 I/O 操作翠订,轉(zhuǎn)而調(diào)度其他線程巢音,避免了因等待 I/O 設(shè)備而造成的進(jìn)程阻塞。
用戶級(jí)線程很快投入使用尽超,Linux系統(tǒng)中的 pthread(POSIX thread)庫可以說是大獲成功官撼,操作系統(tǒng)做出了一項(xiàng)重大決定——支持內(nèi)核級(jí)線程。
內(nèi)核級(jí)線程解決了進(jìn)程并行的問題似谁,除此之外傲绣,由于內(nèi)核看得到線程的存在,一個(gè)線程阻塞了巩踏,位于同一個(gè)進(jìn)程中的其它線程仍然能夠運(yùn)行秃诵。
并行的問題解決了,進(jìn)程表示自己十分開心塞琼。
希望你在看完我的文章之后有所收獲菠净。
感謝你的閱讀,我們后會(huì)有期彪杉!
聲明:原創(chuàng)文章毅往,未經(jīng)授權(quán),禁止轉(zhuǎn)載