2、為什么需要更多的線程

上次談到了什么是線程,那么秉持存在既有價值的原則,我們探討一下為什么需要線程,再附帶一些關鍵性的小問題。


在早期時候,計算機能力比較弱,強調功能性而非易用性,直白點,就是只要能干成,總比我干的快,其他都無所謂。但是隨著時代發(fā)展,對計算機的依賴越來越多,那么要求也越來越多。如果你現在電腦動不動就卡,鼠標轉圈圈,你估計就受不了了,更嚴重的,動不動電腦就要自動重啟,估計你要砸電腦了。但是剛開始,計算機的確是會經常自動重啟的,因為計算機那個時候不分用戶和操作系統(tǒng),落到底層就是,計算機所需要的資源,跟應用程度所需要的資源是放在一起的。上一節(jié)也說過這個情況。這是不安全的,如果應用程序有問題,會導致整個操作系統(tǒng)受牽連。


你可以認為為了解決這個問題,首先讓操作系統(tǒng)使用的空間跟用戶應用程度使用的空間分來了(內核態(tài)和用戶態(tài)),然后為了讓用戶應用之間也不互相影響,大家也都各自在各自的地址空間里面吧。這樣實現了隔離,解決了相互牽連的問題。


后來,人們發(fā)現,應用程序在執(zhí)行的時候,經常會遇到一些執(zhí)行時間比較長的操作,這樣的話,會導致整個應用程序因為等待而不能響應用戶的請求,這樣用戶就會想,這應用有問題。在執(zhí)行長時間任務,比如請求一個遠程文件,這個時候,除了干等著之外,還可以去干點別的。那怎么干呢?


上一節(jié)我們說到線程其實就是一組任務執(zhí)行序列的組合,既然這樣,如果我們把一組任務序列給變成兩組,讓長時間執(zhí)行的一組,短時間執(zhí)行的一組,再加上CPU可以按照時間片切換執(zhí)行序列,這不就可以穿插執(zhí)行兩組任務了嗎?那么對用戶體驗而言,就不需要一直等長時間執(zhí)行的任務,點擊鼠標或者按鈕就可以得到相應了,因為CPU時間片很短。


好了,以前的時候,應用程序分配的地址空間里面只有一個執(zhí)行序列,現在有兩個了,這需要區(qū)分一下。那這個地址空間就叫做進程吧,里面的執(zhí)行序列就叫做線程吧。讀者不要誤會,這個不是段子,進程的概念和線程應該是同時出現的,因為沒有線程,就不需要區(qū)分進程,直接叫地址空間就可以了。地址空間里面本身就有一個執(zhí)行序列,否則應用程序就沒有存在的意義了。所以,進程里面至少有一個線程,但是一個線程,就沒必要單獨區(qū)分了。


那為什么需要更多的線程呢,就是為了讓用戶體驗更好。這個我們就不多說了,先問一個問題,多線程就一定快嗎?


我們來說下串行、并行、并發(fā)的概念,然后再來回答這個問題。


嚴格意義上講,并行和串行和一組概念,并發(fā)跟它們不是一個范疇的概念。串行是指,在一個時間點,只可能有一個任務序列正在被執(zhí)行;并行則是在一個時間點,有至少兩個任務序列正在被執(zhí)行。其實,并行跟串行嚴格上講,跟多不多線程沒關系,它們只跟CPU的個數有關系,只要CPU核數只有一個,再多的線程也是站好成一隊,一個一個執(zhí)行;CPU核數大于1個的時候,那么線程的執(zhí)行序列就可以拍成至少2對,那么就同一時刻,就有多于一個的線程正在被執(zhí)行,這才是并行。


那來說并發(fā),并發(fā)說的是一個時間段內,而非一個時刻。一個時間段內,有多個任務交替進行,是為并發(fā)??梢岳斫鉃椋鼜娬{的是CPU上線程(執(zhí)行序列)的切換以及對一個線程中任務執(zhí)行序列的一個中斷(中斷我們在這里不深究了,操作系統(tǒng)的核心機制)。


并行、串行說的是一個時間點的概念,并發(fā)說的是一個時間段的概念,所以不同。而且并發(fā)可以在并行和串行上轉換,讓我們看一下。在單核CPU上,有3個線程,每個線程需要3個時間片來完成(不考慮CPU上下文切換的時間,雖然這個時間還真不一定可以忽略不計),線程A執(zhí)行上了CPU執(zhí)行一個時間片后就下來了,然后第二個時間片線程C上去了,第二個時間片結束時,線程C下來,然后第三個時間片線程B上去了。現在三個時間片過去了,線程A、B、C都被執(zhí)行了,但是都沒執(zhí)行完,但是都被響應了(聯想一下吞吐量),這個過程是滿足并發(fā)的,但是也滿足串行(在一個時間點,真的就是只有一個線程在執(zhí)行)。在多核CPU上,比如雙核,還是三個線程,每個需要3個時間片來完成。第一個時間片,線程A上了CPU1,線程C上了CPU2,等第一個時間片結束,線程A繼續(xù)在CPU1執(zhí)行,但是線程C從CPU2上下來了,線程C上了CPU2。在這個時間段里面,有多個任務被執(zhí)行響應,而且每個時刻,都真真正正有兩個線程在執(zhí)行,滿足并發(fā)。


現在來回答多線程一定快嗎?

這個需要分情況,情況依賴很多因素,不過我們只需要舉出一個例子,證明不快就可以了。在單核CPU上,CPU因為調度多個線程執(zhí)行需要不斷的切換上下文。在一個時間片快結束時,CPU需要將當前執(zhí)行的線程的狀態(tài)(就是一個臨時變量、PC等值)給記錄下來,以備將來再次執(zhí)行這個線程時,知道如何恢復此時的狀態(tài)(也叫恢復現場)。所以,只要發(fā)生線程切換,勢必就會有上下文切換,說白了,線程切換就是上下文切換,執(zhí)行序列都在線程那里擺好了。上下文切換需要耗費時間,一次保存現場,一次恢復現場。所以,一個任務如果從頭執(zhí)行到尾,可能需要10個時間片,但中間經歷了多次上下文切換,可以總的執(zhí)行時間要變成12個時間片了。那為什么還要多線程呢,因為用戶體驗好。這樣值得嗎?值得,如果用戶體驗不好,沒人用,又有什么意義?客戶就是上帝,呵呵。


為什么需要多線程呢?

因為用戶體驗好,哈哈。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容