線程線程,進程進程,到底什麼是線程,什麼是熟練多線程編程?
今天來和大家一起討論討論區對話基礎,讓大家知道線程的基本構造。
說線程之前,先要瞭解下進程,這個可不能不知道。
什麼是進程?
Microsoft設計作業系統核心時,他們決定在一個進程中運行應用程式的每一個執行個體,進程也不過就是個應用程式執行個體要使用資源的集合。(見過烤玉米,烤甘蔗的沒?如:)
一個進程就好比一個烤筒,一個進程與其他進程互不干涉。作業系統為他們設立了一個虛擬位址空間,確保一個進程使用的代碼和資料無法由另一個進程訪問。這就保證了一個應用程式的健壯性。
現在問題又來了,當一個進程進入無限迴圈了會怎麼樣?
也就是程式沒反應了,無限佔用CUP,使CPU不能執行其他任何東西了,所以,進程是健壯(因為不會被破壞,而且也很安全),但還是會引起系統停止回應,也就是我們常說的“死機”。
這時,Microsoft拿出的解決方案就是線程。也就是說,線程運行於進程之中。
講到線程,先來看看什麼是線程:
- 線程核心對象, Windows為應用程式所建立的每個線程都有一個線程核心對象,這個對象包含一組對線程進行描述的屬性,除此之外,還包含一個線程上下文(thread context),這個上下文是一個記憶體塊,這個記憶體塊用來包含CPU的寄存器集合(什嗎?你不知道CUP寄存器?火速去百度)。
- 線程環境塊,包含一個記憶體塊和一個異常處理鏈,還有些本機存放區資料,GDI圖形使用的一些資料結構。個人感覺沒啥用,知道有就行。
- 使用者模式棧,用來使用者的操作帶來的局部變數和實參,好比函數,程式執行到Add(i),那麼它在執行函數之前會存下進入函數的地址,然後等函數調用完成之後再返回先前記錄的地址,然後執行下一步。這個使用者模式棧也就這用,要知道的是,Windows最少要為它分配1MB記憶體。
- 核心模式棧,在使用者模式棧傳遞實參使會用到核心模式棧,調試大家都用過吧? 在偵錯工具的時候,是不是不能修改代碼了?關鍵就在這,你執行程式之後,使用者模式棧不能訪問核心棧,你寫的代碼都送去核心了。
- DLL線程串連和線程分離通知,用過引用吧?這東西就是你在調用外部程式時需要提前引用一下的原因。載入這個程式,需要用到引用,正如沒有引用,你程式就會出錯。
現在來看看,大家熟悉的工作管理員,對線程來個形象的瞭解:
看到進程了? 看到線程了?
1個線程佔用1MB , 1264個線程就佔用1264MB。我就開了個VS 和SQL 兩個大程式。程式開的不多。
再看看每個進程的線程數:
線程數也看到了,SQL-46個線程,最高記憶體使用量。
再來說說 經常遇到的情景,假設你正在玩一個大型遊戲,突然老師來了,你要裝作你正在幹活,然後Tab+Alt,然後螢幕一黑,急了,怎麼還沒跳過去!!快點啊!!
o(∩_∩)o
現在來說說,一個Alt+Tab,Windows做了哪些事。
Windows之所以能快速接收我們的操作,我們覺得是時時在接收我們的輸入,其實,在你不輸入的時候,此線程已經提前終止此線程,而你的輸入,喚醒文本輸入線程只需要5毫秒。
並且這中間還存在一個叫環境切換的東西,它的切換速度30毫秒,在Windows沒有操作響應的時候,它做的切換工作超乎你的想象,因為有這個功能,保證了Windows的健壯性、快速反應等。
環境切換,不是看不到的,回到那個情景,Alt+Tab,我們現在都知道它是在執行一個不同的線程,在你切換到案頭的時候,
遊戲的線程代碼和資料還在CUP的快取當中(快取能使CPU不需要經常訪問記憶體,它訪問緩衝的速度比記憶體快得多),你的操作使CPU需要訪問新的資料代碼,而這些代碼在記憶體中,
所以CPU又要重新讀記憶體,重新填充告訴緩衝,以恢複高速執行狀態。
好了現在我們知道Alt+Tab發生了什麼事了。環境切換所需時間,取決於CPU架構和速度,填充緩衝取決於應用程式大小和CPU緩衝大小等原因。
以上如有有理解錯誤的地方,請大家提醒指正,謝謝。