執行緒的來龍去脈,你了解嗎?

2021-09-28 12:30:38 字數 2803 閱讀 5413

程序最近有些煩惱,整日愁眉苦臉的,拜訪記憶體的時候也有點心不在焉。

程序嘆了口氣,說道:「唉,最近不是說 cpu 單核頻率到瓶頸了嗎?人類就用多核芯來彌補單核處理器效能的不足,咱們的 cpu 不也公升級到四核了嘛。」

「是啊,這是好事啊,現在最多能並行處理 4 個程序,效率比以前高多了,這還不好嗎?」記憶體疑惑的問。

「好是好,可我每次上 cpu 執行的時候,都忍不住去想,要是單核頻率不增加,我總的執行的時間不還是沒有什麼變化嗎?以後的應用程式越來越大,越來越吃 cpu 資源,比如那些大型遊戲程序,在短時間內需要進行大量計算,靠單核撐不住怎麼辦。不談以後,就說說我自己,我也想能夠早點執行完,早點休息啊。」

tobe 注:很明顯單程序的執行時間是變小了的,不過這裡主要強調的是程序占用 cpu 的時間。

在討論會上,記憶體向大家說明了程序現在遇到的問題。

「乙個程序怎麼並行?」程序排程器第乙個發出疑問:「我總不能把乙個程序放在四個核上吧,這樣不僅毫無意義,還阻礙了其他程序的執行。」

作業系統見多識廣,說:「把程序一次放在幾個核上執行肯定是不可能的,我在想,咱們的目標,其實就是讓多個核心不衝突地幫助乙個程序執行嘛。那我們就得把程序「拆開」,然後放在幾個核上。」

作業系統一邊說,一邊畫了張圖:

「你們看,假如說 fun1 和 fun2 這兩個函式互不關聯,我們就可以讓兩個核同時執行他們,這不就做到並行了嗎?」

「你的意思是說把乙個程序拆成好幾個程序?」

作業系統搖搖頭:「不是拆成多個程序,程序切換的代價太大了,再說了,這些拆出來的函式,他們是共用乙個位址空間的,天生就能夠資料共享,如果拆成程序,我們還得再考慮程序之間的通訊問題,那多麻煩。不過為了跟程序區分,就叫他們「執行緒(thread)」吧」

程序一驚,要把自己拆成執行緒?那自己不就沒了?趕忙問道:「那我豈不是沒有存在的餘地了?」

程序排程器也慌了:「要是沒了程序,我是不是也要被退休了?」

作業系統趕忙解釋道:你們誤會了,我要拆開的,是程序的執行流,程序不是包含了資源所有權執行流嗎,資源所有權還是由程序來把控,執行流就分給幾個執行緒,就像這樣:

tobe 注:在程序模型裡,程序擁有對記憶體、i/o 通道、i/o 裝置和檔案等資源的控制權,稱之為「資源所有權」。「執行流」可以看做程序在 cpu 上的執行過程(直觀一點就是高階語言裡的語句)。

程序恍然大悟:「也就是說我仍然是資源的掌控者,那些執行緒就相當於幫我幹活的小弟?」

「沒錯,而且從這種角度看,你本身還是乙個單執行緒程序。」

聽了這麼久,記憶體發問了:「建立程序的時候,我要儲存程序 pcb ,那為了建立執行緒,我是不是還得建立乙個tcb(thread control block)?」

「當然了,執行緒切換需要的資訊就得存在 tcb 裡面。不過你放心,tcb 要比 pcb 小得多,所以執行緒切換會比程序切換快很多。」

但是作業系統面露難色,說:「執行緒模型只是我們的乙個假想,貿然加進來的話,可能會出問題,系統崩潰可就不好了,還是要以穩定為主。。。但這個模型還是得試的,要不我們先建立乙個執行緒庫,靠乙個使用者級別的應用程式——執行緒排程器來管理這些執行緒吧。」

程序不解的問:「可是這樣的話,我還是被分配在乙個單獨的核心上啊,即使是多執行緒,也只能在單核上執行。再說了,如果這些執行緒裡有乙個被阻塞,在你看來,是整個程序阻塞了,那其他執行緒,即使是就緒態,也得不到 cpu 資源。」

作業系統仔細想了下,說:「沒辦法,使用者級執行緒確實有這兩個缺點,但相比起讓核心來實現執行緒,使用者級執行緒也有他的好處——執行緒切換不需要我進行狀態轉換(從使用者態到核心態),開銷小,除此之外,執行緒庫可以有多個排程演算法,能夠為應用程式量身定做排程演算法。」

tobe 注:有一種解決執行緒阻塞的方案叫

jacketing

,他可以把乙個產生阻塞的系統呼叫轉化成乙個非阻塞的系統呼叫,比如說,不直接呼叫

系統級的 i/o 例程,而是讓執行緒呼叫

應用級的 i/o jacket 例程,這個 jacket 例程會檢查 i/o 裝置是否忙,如果忙的話,就不執行 i/o 操作,轉而排程其他執行緒,避免了因等待 i/o 裝置而造成的程序阻塞。

使用者級執行緒很快投入使用,linux系統中的 pthread(posix thread)庫可以說是大獲成功,作業系統做出了一項重大決定——支援核心級執行緒。

核心級執行緒解決了程序並行的問題,除此之外,由於核心看得到執行緒的存在,乙個執行緒阻塞了,位於同乙個程序中的其它執行緒仍然能夠執行。

並行的問題解決了,程序表示自己十分開心。

希望你在看完我的文章之後有所收穫。

感謝你的閱讀,我們後會有期!

什麼是執行緒安全,你真的了解嗎?

記得今年3月份剛來杭州面試的時候,有一家公司的技術總監問了我這樣乙個問題,說你給我說說有哪些執行緒安全的類,我心裡一想,呵呵,這我早都背好了,稀里嘩啦說了一大堆,那你再來說說什麼是執行緒安全,然後就gg了,說真的,我們整天說執行緒安全,但是你對什麼是執行緒安全真的了解嘛?說真的,我之前真的是了解甚微...

你了解postMessage嗎?

前言 通常,對於兩個不同頁面的指令碼,只有當執行它們的頁面位於同源 同協議 同主機 同埠 情況下,這兩個指令碼才能相互通訊。window.postmessage 方法可以安全地實現跨域通訊 前提 正確使用 使用 語法 otherwindow.postmessage message,targeorig...

你了解你自己的公司嗎?

市場定位是什麼?你是否想像過你現在的客戶都是什麼樣的人?如果可能的話,先試著統計一下他們的基本情況,如 性別 年齡 婚姻狀況 工作內容和工作領域。再想像一下客戶們的價值觀,如他們的生活方式 生活態度等。你對你潛在的客戶了解的越多,就越容易和他們溝通,也越容易取得他們的信賴。無論是新客戶還是老客戶,信...