.net多線程應用


昨天在部門分享.net多線程的一些內容,特此在博客記錄下。內容如下:

進程與線程

1.什么是進程

進程是指在系統中正在運行的一個應用程序
每個進程之間是獨立的,每個進程均運行在其專用且受保護的內存空間內

2.什么是線程

1個進程要想執行任務,必須得有線程(每1個進程至少要有1條線程)
線程是進程的基本執行單元,一個進程(程序)的所有任務都在線程中執行

3.線程的串行

1個線程中任務的執行是串行的
如果要在1個線程中執行多個任務,那么只能一個一個地按順序執行這些任務
也就是說,在同一時間內,1個線程只能執行1個任務

4.什么是多線程

1個進程中可以開啟多條線程,每條線程可以並行(同時)執行不同的任務

並發與並行

並發(concurrency):
在同一時刻只能有一條指令執行,
多個線程程指令被快速的輪換執行

並行(parallel):
在同一時刻,有多條指令
在多個處理器上同時執行。

ps:(上面中的兩個小圖,來自網上,如有侵權,請聯系本人刪除)

 多線程的原理與優缺點

同一時間,單CPU只能處理1條線程,只有1條線程在工作(執行) 多線程並發(同時)執行,
其實是CPU快速地在多條線程之間調度(切換) 如果CPU調度線程的時間足夠快,就造成了多線程並行執行的假象
優點
1、能適當提高程序的執行效率
2、能適當提高資源利用率(CPU、內存、帶寬)

缺點
1、開啟線程需要占用一定的內存空間
    (默認情況下,主線程占用1M,子線程占用512KB)
2、CPU在調度線程上的開銷就越大(上下文切換)
3、並發線程數過高可能出現大量的IO阻塞

如果串行算法可以在不到1S內就能得出結果,那么切換到並行的加速效果不明顯
目前沒有很好的判斷標准,最好的方式就是不停的測試

線程上下文切換,CPU暫停程序執行,將當前寄存器的值保存到內存中,從現有線程中選出一個線程加載上下文結構到寄存器,再開始執行。
Windows大約每30ms執行一次垃圾回收,CLR會暫停所有的線程,遍歷所有的對象進行垃圾清除。

線程安全的集合

System.Collections.Concurrent命名空間下的類型來用於並行循環體內。

說明

BlockingCollection<T>

為實現 IProducerConsumerCollection<T> 的線程安全

集合提供阻止和限制功能。

ConcurrentBag<T>

表示對象的線程安全的無序集合。

ConcurrentDictionary<TKey, TValue>

表示可由多個線程同時訪問的鍵值對的線程安全集合。

ConcurrentQueue<T>

表示線程安全的先進先出 (FIFO) 集合。

ConcurrentStack<T>

表示線程安全的后進先出 (LIFO) 集合。

OrderablePartitioner<TSource>

表示將一個可排序數據源拆分成多個分區的特定方式。

Partitioner

提供針對數組、列表和可枚舉項的常見分區策略。

Partitioner<TSource>

表示將一個數據源拆分成多個分區的特定方式。

 

線程狀態

成員名稱

說明

Aborted

線程處於 Stopped 狀態中。 

AbortRequested

已對線程調用了 Thread.Abort 方法,但線程尚未收到試圖終止它的掛起的System.Threading.ThreadAbortException。 

Background

線程正作為后台線程執行(相對於前台線程而言)。此狀態可以通過設置Thread.IsBackground 屬性來控制。 

Running

線程已啟動,它未被阻塞,並且沒有掛起的 ThreadAbortException。 

Stopped

線程已停止。 

StopRequested

正在請求線程停止。這僅用於內部。 

Suspended

線程已掛起。 

SuspendRequested

正在請求線程掛起。 

Unstarted

尚未對線程調用 Thread.Start 方法。 

WaitSleepJoin

由於調用 Wait、Sleep 或 Join,線程已被阻止。 

C#多線程環境下調用 HttpWebRequest 並發連接限制

.net 的 HttpWebRequest 或者 WebClient 在多線程情況下存在並發連接限制,這個限制在桌面操作系統windows 7 下默認是2,在服務器操作系統上默認為10。不修改這個並發連接限制,客戶端同時可以建立的 http 連接數就只有2個或10個。

經過驗證,在.net core下也是如此。

.net cor中源碼地址:https://github.com/dotnet/corefx/blob/master/src/System.Net.Requests/src/System/Net/HttpWebRequest.cs

對應的.net freamwork中的代碼:

之所以有這個並發連接限制,是因為 http 1.0 和 http 1.1 標准規定並發連接數最大為2.。不過目前主流的瀏覽器都已經不遵循這個規則了,但 .net 依然默認遵循這個規則。

對於.net core,這個設置系統級別的,不過沒讀注冊表。。。對了,linux沒注冊表。當應該讀系統的環境變量才行的。(作者未驗證,歡迎驗證過的同學評論)

解決辦法:

System.Net.ServicePointManager.DefaultConnectionLimit = 512;  //第一種
//HttpWebRequest.ServicePoint.ConnectionLimit=512;          //第二種

.net freawork 下,也可以在配置文件app.config中設置:

<system.net>
    <defaultProxy enabled="false">
      <proxy/>
      <bypasslist/>
      <module/>
    </defaultProxy>

    <connectionManagement>
      <add address="*" maxconnection="10"/>
    </connectionManagement>

  </system.net>

另外提一點:HttpWebRequest默認會使用IE代理設置,上面的配置文件設置不啟用代理。

還有一種方法 httpWebRequest.Proxy = null;

這樣可以減少.net使用代理所需要花費的時間和占用的資源。

Demo

針對上述理論,我寫了Thread 、 Task  、Parallel 的各種demo ,以及多線程的取消的Demo。由於篇幅有限,就在此不做展示,源代碼地址:

 https://github.com/li-shaoke/ThreadDemo

 

參考自:

https://www.cnblogs.com/summer_adai/archive/2013/04/26/3045274.html

https://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM