《CLR Via C#》讀書筆記:26.線程基礎

来源:https://www.cnblogs.com/myzony/archive/2018/11/04/9906234.html
-Advertisement-
Play Games

一、線程開銷 操作系統創建線程是有代價的,其主要開銷在下麵列舉出來了。 記憶體開銷 1. 線程內核對象 擁有線程描述屬性與線程上下文,線程上下文占用的記憶體空間為 x86 架構 占用 700 位元組、x64 架構 1240 位元組 、ARM 架構 350 位元組。 2. 線程環境塊(TEB) TEB 消耗一個 ...


一、線程開銷

操作系統創建線程是有代價的,其主要開銷在下麵列舉出來了。

記憶體開銷

  1. 線程內核對象

    擁有線程描述屬性與線程上下文,線程上下文占用的記憶體空間為 x86 架構 占用 700 位元組、x64 架構 1240 位元組 、ARM 架構 350 位元組。

  2. 線程環境塊(TEB)

    TEB 消耗一個記憶體頁,占用 4KB記憶體。

  3. 用戶模式棧。

    用戶模式棧存儲傳遞給方法的局部變數與實參,並且還存儲有一個地址用於當前方法返回的時候,線程應該從哪個地方繼續執行。預設 Windows 分配保留 1MB 記憶體。

  4. 內核模式棧。

    32 位 Windows 占用 12 KB,64 位 Windows 占用 24 KB。

  5. DLL 線程連接與線程分離通知。

    這種策略只有 Windows 才會存在,當創建線程時, Windows 會調用進程所有非托管 DLL 的 DllMain 方法,並未其傳遞 DLL_THREAD_ATTACH 標誌,線程終止時傳遞 DLL_THREAD_DETACH 標誌。

線程上下文切換與 CPU 之間的關係

Windows 在任何時刻都只會將 1 個線程分配給 1 個 CPU ,該線程享有一個時間片的運行時間。時間片到期之後,Windows 會將上下文切換到另外一個線程,動作如下:

  1. 將 CPU 寄存器值存儲在當前正在運行的線程的內核對象內部的上下文結構之中。
  2. 從先有線程集合選取一個線程供調度,如果該線程屬於另一個進程,還得切換 CPU 能夠操作的虛擬地址空間。
  3. 將上下文結構中的值載入到 CPU 寄存器之中。

以上操作做完之後,Windows 等待這個線程時間片到期,執行下次切換,每次切換的時間開銷大概為 30 毫秒。

如果一個線程時間片結束之後,下一個調度的線程還是之前的線程則不會產生線程上下文切換。

所以在理想狀態下,每個系統最佳的線程數應該與其核心數相同,(如果是 4 核 8 線程則最優應該為 8 個)因為這樣上下文切換出現的情況就會少很多。

最重要的是,Windows 系統上大部分程式線程都處於空閑狀態,但是線程占用的記憶體空間是事實存在的。

三、使用專用線程執行計算限制的非同步操作

一般來說不推薦使用 Thread 手動創建線程,而應該使用線程池,不過在有以下需求時,可以手動創建線程。

  1. 需要設定更高的線程優先順序的時候。
  2. 需要將線程設置為前臺線程。
  3. 某些長耗時的專用線程。
  4. 該線程可能會通過 Thread 的 Abort 方法終止自身。

在調用過程中,如果使用了 Thread.Join() 方法那麼就會造成調用線程阻塞當前代碼,直到創建的線程被終止。

四、為什麼要使用線程

  1. 針對於客戶端程式而言,多線程可以增強響應性,不會因為耗時操作阻塞 UI 線程造成用戶體驗卡頓。
  2. 針對於伺服器程式而言,可以併發地處理用戶請求,充分利用多核 CPU 的優勢。

作者的觀點是,電腦的 CPU 使用率應該保持 100% 的使用率才不算是浪費計算資源。

五、線程調度與優先順序

搶占式系統通過優先順序來判定線程在什麼時候調度多少時間,每個線程都分配了從 0 到 31 的優先順序,系統為 CPU 分配線程時,首先檢查 31 的線程,並以輪詢的方式調度他們(優先順序都為 31)。

如果高優先順序的線程一直處於調度狀態,那麼操作系統不會將 CPU 分配給低優先順序的線程,這樣就會造成 線程饑餓

較高的優先順序線程總會搶占低優先順序線程,即便該線程的時間片沒有用完。

CPU 會創建一個優先順序為 0 的 零頁線程 ,該線程是系統唯一一個優先順序為 0 的線程,只有在 CPU 空閑的時候會執行他,用於清理 RAM 中所有的空閑記憶體頁。

【註意】

進程優先順序類 + 線程優先順序構成了一個基礎優先順序,Windows 還有一個動態優先順序用於防止產生線程饑餓,會動態調成線程的優先順序狀態。

但是動態優先順序只會針對基礎優先順序在 0 ~ 15 的線程應用,16 ~ 31 不受這個管控。

Windows 通過兩個抽象層用於表示進程優先順序類和線程優先順序,單一般 C# 用戶代碼中能夠控制的只有線程優先順序,他們分別是:Lowest、BelowNormal、Normal、AboveNormal、Highest。

六、前臺線程與後臺線程

在 CLR 中線程只有兩種狀態,前臺線程和後臺線程,而且當所有前臺線程被終止之後,CLR 會強行關閉所有後臺線程,並退出程式。

線程在運行的生命周期當中可以變更其狀態,但主線程預設為前臺線程,使用 Thread 類型創建的線程預設也是前臺線程。只有線程池的線程預設為後臺線程,進入托管執行的本機代碼創建的任何線程也會標記為後臺線程。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 非同步asyncio asyncio是一個使用async / await語法編寫併發代碼的庫。 asyncio用作多個Python非同步框架的基礎,這些框架提供高性能的網路和Web伺服器,資料庫連接庫,分散式任務隊列等。 asyncio通常非常適合IO綁定和高級 結構化網路代碼。 asyncio提供了一 ...
  • 使用BeautyEye L&F 漂亮外觀 ...
  • 配置PHP開發環境的時候,當進行到在Apache的httpd.conf文件中配置載入PHP模塊時發生如下錯誤 httpd: Syntax error on line 185 of D:/wamp/Apache24/conf/httpd.conf: Cannot load D:/wamp/php 5. ...
  • Like music and movies, video games are rapidly becoming an integral part of our lives. Over the years, youve yearned for every new gaming console, mas ...
  • 1.arrary_merge 示例代碼: 運行上面的代碼,輸出結果如下圖所示: 普通數組合併時,會把第二個數組放到第一個數組後面,拼接後返回。 但是對於鍵值對的數組來說,如果有相同的鍵,那麼第二個數組會覆蓋第一個數組相同的鍵所對應的值。 2.通過 合併 示例代碼: 運行上面的代碼,輸出結果如下圖所示 ...
  • datetimepicker造成的問題,年、月和日參數描述無法表示的 DateTime ...
  • 原則的誕生:面向對象:封裝、繼承、多態三大支柱蘊含了用抽象來封裝變化,降低耦合,實現復用的精髓; 封裝:隱藏內部的實現,保護內部信息; 繼承:實現復用,歸納共性; 多態:改寫對象行為,實現更高級別的繼承 要實現這些目的,就必須遵守一些原則:封裝變化、對介面編程、少繼承多聚合 實現系統的可擴展、可復用 ...
  • FormsAuthentication.SetAuthCookie(UserFlag, createPersistentCookie); createPersistentCookie是否永久保存cookie https://www.cnblogs.com/joeylee/p/3521131.html ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...