多執行緒程式設計(一) 揭開執行緒的神秘面紗

2022-02-13 03:23:05 字數 2005 閱讀 1400

一、windows為什麼要支援執行緒

早期作業系統的狀況:早期,作業系統沒有執行緒的概念。整個系統只執行著乙個執行執行緒,其中同時包含作業系統**和應用程式**。

問題:長時間執行的任務會阻止其他任務的執行。某個應用程式的執行可能會凍結整個機器,造成os和其他應用程式停止響應。如果應用程式有bug,會造成無線迴圈,同樣會造成整個機器停止工作,並且會導致資料丟失。

改進:構建乙個新的os來滿足企業和個人的需要。

1、ms在設計這個os的核心時。決定在乙個程序中執行應用程式的每個例項。程序是應用程式的乙個例項要使用的資源的乙個集合。每個程序都被賦予了乙個虛擬的位址空間,確保乙個程序使用的**和資料無法由另乙個程序訪問。這就確保了應用程式例項的健壯性,因為乙個程序無法破壞另乙個程序使用的**和資料。除此之外,os的核心**和資料是程序訪問不到的,所以應用程式破壞不了作業系統的**和資料。

2、但是cpu本身呢?如果乙個應用程式進入無限迴圈,並且機器中只有乙個cpu,那他會執行無限迴圈,不能執行其他任何東西。所以,系統還是可能會停止響應。ms對於這個問題拿出的解決方案是執行緒。執行緒的職責是對cpu進行虛擬化。windows為每個程序都提供了該程序專用的執行緒(功能相當於乙個cpu,可將執行緒理解為乙個邏輯cpu)。如果應用程式的**進入無線迴圈,與那個**關聯的程序會「凍結」,但其他的程序還會繼續執行。

二、執行緒開銷

和一切虛擬化機制一樣,執行緒會產生空間(記憶體耗用)和時間(執行時的執行效能)上的開銷。

每個執行緒中,都有以下要素:

1、執行緒核心物件。

2、執行緒環境塊。

3、使用者模式棧。

4、核心模式棧。

5、dll執行緒鏈結和執行緒分離通知。

建立和終止執行緒引起的開銷:任何時候在程序中建立乙個執行緒,都會呼叫那個程序中載入的所有dll的dllmain方法,並向該方法傳遞乙個dll_thread_attach標識。類似的,任何時候乙個執行緒終止,都會呼叫程序中的所有dll的dllmain方法,並向該方法傳遞乙個dll_thread_detach標識。(注:c#和其他大多數的程式語言生產的dll沒有dllmain函式,所以託管dll不會收到dll_thread_attach和dll_thread_detach的通知,這提公升了效能。)

上下文切換引起的開銷:單cpu的計算機一次只能做一件事情。所以windows必須在系統中的所有執行緒(邏輯cpu)之間共享物理cpu。在任何給定的時刻,windows只將乙個執行緒分配給乙個cpu,那個執行緒允許執行乙個「時間片」,一旦時間片到期,windows就上下文切換到另乙個執行緒,每次上下文切換都要求windows執行以下操作:

1、將cpu暫存器中的值儲存到當前正在執行的執行緒的核心物件內部的乙個上下文結構中。

2、從現有的執行緒集合中選出乙個執行緒供排程。如果該執行緒有由另乙個程序擁有,windows在開始執行任何**或者接觸任何資料之前,還必須切換cpu「看見」的虛擬位址空間。

3、將所選上下文結構中的值載入到cpu的暫存器中。

windows大約每30毫秒執行一次上下文切換。上下文切換是淨開銷:也就是說上下文切換所產生的開銷不會換來任何記憶體或者效能上的收益。windows執行上下文切換,向使用者提供乙個健壯的、響應靈敏的作業系統。執行上下文切換所需要的時間取決於cpu架構和速度。而填充cpu快取所需時間取決於系統中執行的應用程式、cpu快取的大小及其他各種因素。所以無法為每一次上下文切換的時間開銷給出乙個確定的值,甚至無法給出乙個估計的值。唯一確定的是,如果要構建高效能的應用程式和元件,就應該盡可能的避免上下文切換。

在執行垃圾**時,clr必須掛起(暫停)所有執行緒,遍歷他們的棧來查詢跟以便對對堆中的物件進行標記,再次遍歷他們的棧(物件在壓縮期間可能發生了移動,所以要更新他們的根),再恢復所有執行緒。所以,減少執行緒的數量會限制提公升垃圾**器的效能。

未完待續.........

讓我們一起揭開演算法的神秘面紗

前言 其實我一直想寫一篇揭秘演算法的文章,因為,據我所見,大多數寫演算法的軟體工程師,其實,就是普通程式設計師,並非高人一等。但我一直不知道從何下手,今天姑且嘗試著亂寫一點。最唬人的高大上 演算法最唬人的東西莫過於公式了。而公式中最唬人的摸過於 了 這個符號叫sigma,如下圖 舉個例子 某公司開會...

多執行緒程式設計(一)

程式 完成特定功能的一系列指令的集合 c 源程式 經過編譯鏈結後生成可執行檔案,可執行檔案稱為程式,它包含 段和資料段。儲存在磁碟上 程序 程式的一次動態執行過程,強調動態性,它包括 段 資料段 堆疊段 pcb 乙個程序只能對應乙個程式,乙個程式可以對應對個程序 執行緒 在乙個程式裡的乙個執行線路就...

多執行緒程式設計(一)

引用標頭檔案thread 建立執行緒 thread mythread 多執行緒函式 阻塞主線程直到子執行緒執行完畢 mythread.join 分離主線程和子執行緒,使得主線程和子執行緒可以同步執行下去 一旦分離後,就無法再使執行緒join 主線程結束後子執行緒也結束 mythread.detach...