1. 程式人生 > >03-解析多執行緒與多程序的聯絡以及上下文切換所導致資源浪費問題

03-解析多執行緒與多程序的聯絡以及上下文切換所導致資源浪費問題

什麼是程序?簡單來講就是執行中的程式,那麼,何為執行中的程式呢?我們如何來看看程序呢?作業系統都是多程序的。我們通過工作管理員就可以看到作業系統中當前執行的很多的程序

我們寫過的任何的一個程式,我們寫一個程式,那麼,這個程式執行起來,它就稱之為程序。

程序和執行緒之間又有什麼關係呢?這裡簡單給大家提幾點,程序是資源分配的基本單位。如果大家對程序比較感興趣的話,你可以去了解一下咱大學中所學的《作業系統原理》這本書,這本書裡面就詳細的講解了程序。 程序和執行緒之間到底有什麼關聯呢?首先,程序是資源分配的基本單位。第二個,程序中包含多個執行緒,執行緒共享程序的資源。我們可以這麼理解,就是說,程序是作業系統級別的,一個作業系統運行了多個程序,每一個程序裡面有包含著多個執行緒,我們可以通過下圖這個地方來看

這裡面有一個CPU的統計資訊,此處有一個程序數是137,就是,運行了137個程序,執行緒有1720個,顯然執行緒的數量遠遠大於程序的數量,也就是說,一個程序裡面會有多個執行緒。我們的eclipse軟體就是一個程序,我們看一個程序中到底包含了多少個執行緒呢?我們之前也通過jconsole監控工具

也就是說,這一個程序中,目前所包含的執行緒數量使29個。

執行緒是共享程序的資源,這句話,就是說,程序是作業系統級別的,那麼,執行緒就是程序級別的,你可以這樣理解,作業系統裡面包含多個程序,而一個程序裡面有包含多個執行緒。第三個,執行緒是處理器排程的基本單位。為什麼處理器排程的基本單位是執行緒而不是程序?我們說,程序是資源分配的基本單位,在進行程序之間的切換的過程中,它會浪費更多的資源,然而,執行緒可以說是輕量級的程序,所以,CPU的排程的基本單位是執行緒。

這就是執行緒和程序之間的聯絡與區別

 

多執行緒執行一定會快嗎?我們大家可能都知道在很多的下載的網站上,都會提多執行緒下載,那麼,我們也同樣的發現,使用多執行緒下載遠比單執行緒下載要快的多,這樣,可能大家都會認為多執行緒一定比單執行緒快,其實並不一定,我們來舉個例子,還是拿之前烤燒餅的例子來說,

下面只有一個爐火,上面在不停的轉,這樣烤一定會快嗎?咱大家想一下,我們現在是多個執行緒在執行,如果我們不這樣做,我們不讓它轉,

就讓它烤這一個,等它烤熟了之後,我們再拿另外一個,再放進來烤,然後依次類推,那麼,我們想一下,是之前的全部放上去讓爐子轉起來烤,烤的快呢?還是我一個一個放上去烤,烤的快呢?其實是非常明顯的,如果選在轉的話,在轉的過程中,每個燒餅(執行緒)切換的過程中是有空隙的

那麼,火就浪費了,這是第一個,第二個,在加熱的工程中,能量都集中在在一個塊上

如果你在轉,那麼,熱量是分散在整個爐子上面的

這樣也會損失熱量,總之就是說,執行緒任務之間在進行切換,也就是說,燒餅在進行切換的過程中,它是要浪費我們的資源的,也就是要浪費我們的能量的,因此,其實是遠遠不如一個一個的執行反而更快一些,那麼,有沒有實際的例子來說明呢,烤燒餅是我們生活中的一個例子,我們來舉一個變成界的例子,我們知道垃圾收集,垃圾收集,它有一些垃圾收集演算法,比如說,像複製演算法、標記清除演算法、標記整理演算法、分代收集演算法等等,它有很多的演算法,我們這裡要說的就是和垃圾收集器相關的問題,垃圾收集器有非常多,有多執行緒執行的垃圾收集器,或者說是並行執行的垃圾收集器,而serial垃圾收集器是單執行緒執行的,一個單執行緒執行的垃圾收集器,既然有了多執行緒執行的垃圾收集器,為什麼還會有serial單執行緒垃圾收集器呢?存在的就是合理的,其實並非多執行緒的就一定快,你讓單執行緒的serial垃圾收集器收集垃圾去了,那麼,它沒有二心思,就一味的去收集幹活,一直等它幹完活之後就結束了,而多執行緒垃圾收集器,它們的事比較多,一邊想著幹活,一邊還得再進行執行緒之間的切換,那麼,對於佔用記憶體比較少的,回收時間本來就比較短的,那麼,完全就可以使用單執行緒的垃圾收集器來進行收集,而它的效能是遠比多執行緒要快的,就是在某些情境下單執行緒是遠比多執行緒要快的。

這就是關於多執行緒的效能問題,我們在之前提到過執行緒的缺點上也說過,線上程之間切換的時候,是非常耗效能的,每一個執行緒的建立和銷燬更是對資源的浪費是非常大的,當然了,如果你這個地方不是一個爐子,而是有多個爐子,那麼,此時多個執行緒就快了,所以,就是說,多執行緒快還是不快,它不是絕對的。回過頭我們再來解釋剛才提到的關於迅雷下載,就是說,多執行緒下載的問題,多執行緒下載為什麼一定能夠提高,也並非一定能夠提高下載的速度,但是,絕大部分情況下是可以的,為什麼呢?因為,我們說,做一個檔案伺服器的話,允許使用者去下載,那麼,它肯定不會說你這個連結過來了,我就會毫無保留的一下子把我的頻寬全部給你,讓你去下載,我肯定是為每一個連結分配一定的頻寬,比如說,你這一個連線進來,我就給你這個響應最高200k,不能再多了,那麼也就是說,你這一個連結進來,它的峰值下載速度也就是200k,那麼,它是一個連結級別的,那麼,我可以把要下載的一個檔案分成多個,切分成多個,我用多個執行緒一塊去下載,那麼,每一個連結200k,假設有三個連結,那麼,加起來就是一共有600k的下載速度,那麼,等我把切分的每一小塊檔案都下載完了之後,我在把這些小檔案合併起來就可以了,這樣,下載的速度就會變的很快,也就是說,多執行緒下載並不是多執行緒提高了速度,不是多執行緒的效能提高了,而是,由於外部伺服器對資源的限制,所導致的一個問題,那麼,多個連結就突破了這個遠端伺服器的限制,也就導致了效能的提高。也就是說,雖然看著下載速度快了,並不是多執行緒的效能提高了,而是由於遠端伺服器的問題。