.Net 線程與鎖

来源:https://www.cnblogs.com/Sol-wang/archive/2022/10/20/14793008.html
-Advertisement-
Play Games

1、如何在Asp.Net Core中激活Session功能 首先添加Session包,其次在ConfigService方法中添加Session,然後在ConfigService中調用useSession。 2、什麼是中間件 指註入到應用中處理請求和響應的組件,是通過多個嵌套形成的 3、Applica ...


一臺伺服器能運行多少個線程,大致取決於CPU的管理能力。CPU負責線程的創建、協調、切換、銷毀、暫停、喚醒、運行等。

一個應用程式中,必須有一個進程,一個進程可同時多個線程協作處理。

同步:單線程,每一步都執行結束並返回結果,下一步處於等待,阻塞程式流

非同步:多線程,不需要等待執行結束,可繼續執行下一步,形成並行處理,無序的不可預測的執行順序

前臺線程:主線程退出後,子線程直至完成計算。

後臺線程:主線程退出後,子線程也會停止退出。

 

線程的應用

常用的線程創建方式

  • new Thread
  • ThreadPool.QueueUserWorkItem 後臺線程
  • delegate 委托 invoke
  • Task.Run / Task.Factory.StartNewd
  • Parallel
  • await / async

 

ThreadPool 線程池

每個進程都有一個線程池,每個線程池依環境因素分配不同的線程數
由線程池統一管理每個線程的創建/分配/銷毀。

// 設置可同時並行運行的線程數
ThreadPool.SetMinThreads
ThreadPool.SetMaxThreads
// 用線程池中的後臺線程執行方法
ThreadPool.QueueUserWorkItem(方法1);

 

Task

Task所用到的線程同樣來自於ThreadPool。

Action<object> action = (object obj) =>
{
    Console.WriteLine("Task={0}, obj={1}, Thread={2}",
    Task.CurrentId, obj,
    Thread.CurrentThread.ManagedThreadId);
};

// Create a task but do not start it.
Task t1 = new Task(action, "alpha");

// Construct a started task
Task t2 = Task.Factory.StartNew(action, "beta");
// Block the main thread to demonstrate that t2 is executing
t2.Wait();

// Launch t1 
t1.Start();
Console.WriteLine("t1 has been launched. (Main Thread={0})",
Thread.CurrentThread.ManagedThreadId);
// Wait for the task to finish.
t1.Wait();

// Construct a started task using Task.Run.
String taskData = "delta";
Task t3 = Task.Run( () => {
    Console.WriteLine("Task={0}, obj={1}, Thread={2}",
    Task.CurrentId, taskData,
    Thread.CurrentThread.ManagedThreadId);
});
// Wait for the task to finish.
t3.Wait();

// Construct an unstarted task
Task t4 = new Task(action, "gamma");
// Run it synchronously
t4.RunSynchronously();
// Although the task was run synchronously, it is a good practice
// to wait for it in the event exceptions were thrown by the task.
t4.Wait();


// Task 的返回值(等待返回結果)
Task<int> task = new Task<int>(() =>
{
    //...
    return 0;
});
task.Start();
int result = task.Result;


// 僅僅啟動一個Task
Task.Run(() =>
{
    //...
});


// 批量啟動 Task
// 同時並行運行至少30個線程的方式
ThreadPool.SetMinThreads(30, 50);
ThreadPool.SetMaxThreads(50, 70);
for (int i = 0; i < 30; i++)
{
    Task.Run(() =>
    {
        //...
    });
}

 

Parallel

多線程並行處理的 Parallel.Invoke,Parallel.For,Parallel.ForEach;無法確保順序處理。

// 示例:並行運行幾個方法
Parallel.Invoke(方法1, 方法2, () => 方法3, () => 方法4)



// ParallelOptions 參數設定
// 先指定啟用30個線程同時處理的設置
ParallelOptions paroptions = new ParallelOptions();
paroptions.MaxDegreeOfParallelism = 30;



// 指定數量的線程,並行執行200遍
List<int> datas = new List<int>();
Parallel.For(0, 200, paroptions, index =>
{
    datas.add(index);
});



// 指定數量的線程,並行讀取數據
Parallel.ForEach(datas, paroptions, (item) =>
{
    Console.WriteLine(item);
});

 

await / async

創建後臺進程並行處理,並取得處理結果。

// 執行 async 方法(後臺線程執行)
Task<string> _task_result_1 = t1.Func1();
// 主線程不等返回結果,繼續往下執行

// 執行方法
string _result_2 = t1.Func2();
// 以上兩個方法並行執行

// 取 Func1 的運行結果
string _result_1 = await _task_result_1;

// 整合兩個方法的運行結果
int _total_ = _result_1.length + _result_2.length;

 

常用的線程鎖

lock

封裝自應用級鎖Monitor類,需要有線程共用的鎖標識,告知其它線程是否等待。

 

Monitor

程式級鎖,於單個應用範圍內

// 給要操作的對象加把鎖,排他鎖
Monitor.Enter(T);
// 釋放當前鎖,允許其它線程使用了
Monitor.Exit(T);

 

Semaphore

限制可同時訪問某一資源或資源池的線程數,允許同時共用的線程數

// 創建時,定義同時的預設線程數和最多線程數(起始線程數,最多線程數)
Semaphore sem = new Semaphore(10, 20);
// 上鎖
sem.WaitOne();
// 釋放鎖(一次釋放線程數)
sem.Release(3);

 

Mutex

系統級鎖,內核對象,所以可跨進程跨應用
// 阻擋鎖住當前塊,其它線程處於等待
// 超時後返回false,不允許其它線程進入
Mutex.WaitOne(timeout);
// 釋放當前,一個,允許其它線程進入
Mutex.ReleaseMutex();

 

線程安全

線程安全的類,通過 lock(xxx.SyncRoot) 實現線程同步,如:Array,ArrayList

線程安全的高性能集合類

ConcurrentBag 無序集合

ConcurrentStack 後進先出

ConcurrentQueue 先進先出

ConcurrentDictionary 鍵值對字典

 

個人拙見,有不妥望指出,萬分感謝。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄 一.OpenGL 圖像伽馬線 1.原始圖片 2.效果演示 二.OpenGL 圖像伽馬線源碼下載 三.猜你喜歡 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 ...
  • 什麼是標識符? 標識符是用來標識變數、函數、類、模塊,或者任何其他用戶自定義項目的名稱,用它來命名程式正文中的一些實體,比如函數名、變數名、類名、對象名等。如:int a1=0; const b1="hello"中 a1和b1都是標識符,不過a1是變數,也就是存儲單元的標識符,b1是數據字元串的標識 ...
  • 前言 最近學校開設了JAVA_EE課程,課上講到了struts1框架,並且需要做相關試驗。由於習慣了使用IDEA,便嘗試在IDEA上部署struts1框架。 環境 windows10 21H2 IntelliJ IDEA 2022.1.4 (Ultimate Edition) ps: 如果是在校學生 ...
  • 設計一個程式統計某班全體學生3門課的考試成績。要求先輸入學生人數,並輸入每個學生的三門成績,統計出每門課程的全班平均分及每個考生所有考試的總分。 #include<stdio.h>#include<math.h>int b,i,q,j,n,sum,avg,all;int a[20][3];//可以為 ...
  • C語言實現staque結構 1. 使用說明 staque結構以單鏈表方式實現,結合了stack與queue結構:pop_front+push_front使用方式為stack;pop_front+push_back使用方式是queue。 首尾插入和頂部彈出是運行效率最高的,此外還實現了任意位置的插入、 ...
  • 原創:扣釘日記(微信公眾號ID:codelogs),歡迎分享,轉載請保留出處。 簡介 前面在密碼學入門一文中講解了各種常見的密碼學概念、演算法與運用場景,但沒有介紹過代碼,因此,為作補充,這一篇將會介紹使用Java語言如何實現使用這些演算法,並介紹一下使用過程中可能遇到的坑。 Java加密體系JCA J ...
  • 之前在學習servlet和jsp時學習了過濾器Filter,使用過濾器需要實現Filter介面,它能夠在請求到servlet之前攔截請求,並且根據需求對請求進行相應的處理。 攔截器跟過濾器非常相似,SpringMVC攔截器是通過實現HandlerInterceptor介面實現的,它其實是AOP的一種 ...
  • 本文主要概述 Logstash 的一些最受歡迎的輸入插件,以大致瞭解 Logstash 的用途;相關的環境及軟體信息如下:CentOS 7.9、Logstash 8.2.2。 1、什麼是 Logstash input 插件 Logstash 用作日誌管道,用於偵聽已配置日誌源(例如,應用程式,資料庫 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...