日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结

發布時間:2025/6/17 C# 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

5天玩轉C#并行和多線程編程 —— 第五天 多線程編程大總結

5天玩轉C#并行和多線程編程系列文章目錄

5天玩轉C#并行和多線程編程 —— 第一天 認識Parallel

5天玩轉C#并行和多線程編程 —— 第二天 并行集合和PLinq

5天玩轉C#并行和多線程編程 —— 第三天 認識和使用Task

5天玩轉C#并行和多線程編程 —— 第四天 Task進階

5天玩轉C#并行和多線程編程 —— 第五天 多線程編程大總結

?

?一、多線程帶來的問題

1、死鎖問題?

  前面我們學習了Task的使用方法,其中Task的等待機制讓我們瞬間愛上了它,但是如果我們在調用Task.WaitAll方法等待所有線程時,如果有一個Task一直不返回,會出現什么情況呢?當然,如果我們不做出來的話,程序會一直等待下去,那么因為這一個Task的死鎖,導致其他的任務也無法正常提交,整個程序"死"在那里。下面我們來寫一段代碼,來看一下死鎖的情況:

var t1 = Task.Factory.StartNew(() =>{Console.WriteLine("Task 1 Start running...");while(true){System.Threading.Thread.Sleep(1000);}Console.WriteLine("Task 1 Finished!");});var t2 = Task.Factory.StartNew(() =>{Console.WriteLine("Task 2 Start running...");System.Threading.Thread.Sleep(2000);Console.WriteLine("Task 2 Finished!");});Task.WaitAll(t1,t2);

這里我們創建兩個Task,t1和t2,t1里面有個while循環,由于條件一直為TRUE,所以他永遠也無法退出。運行程序,結果如下:

可以看到Task2完成了,就是遲遲等不到Task1,這個時候我們按回車是沒有反應的,除非關掉窗口。如果我們在項目中遇到這種情況是令人很糾結的,因為我們也不知道到底發生了什么,程序就是停在那里,也不報錯,也不繼續執行。

那么出現這種情況我們該怎么處理呢?我們可以設置最大等待時間,如果超過了等待時間,就不再等待,下面我們來修改代碼,設置最大等待時間為5秒(項目中可以根據實際情況設置),如果超過5秒就輸出哪個任務出錯了,代碼如下:

Task[] tasks = new Task[2];tasks[0] = Task.Factory.StartNew(() =>{Console.WriteLine("Task 1 Start running...");while(true){System.Threading.Thread.Sleep(1000);}Console.WriteLine("Task 1 Finished!");});tasks[1] = Task.Factory.StartNew(() =>{Console.WriteLine("Task 2 Start running...");System.Threading.Thread.Sleep(2000);Console.WriteLine("Task 2 Finished!");});Task.WaitAll(tasks,5000);for (int i = 0; i < tasks.Length;i++ ){if (tasks[i].Status != TaskStatus.RanToCompletion){Console.WriteLine("Task {0} Error!",i + 1);}}Console.Read();

這里我們將所有任務放到一個數組里面進行管理,調用Task.WaitAll的一個重載方法,第一個參數是Task[]數據,第二個參數是最大等待時間,單位是毫秒,這里我們設置為5000及等待5秒鐘,就繼續向下執行。下面我們遍歷Task數組,通過Status屬性判斷哪些Task沒有完成,然后輸出錯誤信息。

?

2、SpinLock(自旋鎖)

  ?我們初識多線程或者多任務時,第一個想到的同步方法就是使用lock或者Monitor,然而在4.0 之后微軟給我們提供了另一把利器——spinLock,它比重量級別的Monitor具有更小的性能開銷,它的用法跟Monitor很相似,VS給的提示如下:

下面我們來寫一個例子看一下,代碼如下(關于lock和Monitor的用法就不再細說了,網上資料很多,大家可以看看):

SpinLock slock = new SpinLock(false);long sum1 = 0;long sum2 = 0;Parallel.For(0, 100000, i =>{sum1 += i;});Parallel.For(0, 100000, i =>{bool lockTaken = false;try{slock.Enter(ref lockTaken);sum2 += i;}finally{if (lockTaken)slock.Exit(false);}});Console.WriteLine("Num1的值為:{0}", sum1);Console.WriteLine("Num2的值為:{0}", sum2);Console.Read();

輸出結果如圖:

這里我們使用了Parallel.For方法來做演示,Parallel.For用起來方便,但是在實際開發中還是盡量少用,因為它的不可控性太高,有點簡單粗暴的感覺,可能帶來一些不必要的"麻煩",最好還是使用Task,因為Task的可控性較好。

slock.Enter方法,解釋如下:

?

3、多線程之間的數據同步

  多線程間的同步,在用thread的時候,我們常用的有lock和Monitor,上面剛剛介紹了.Net4.0中一個新的鎖——SpinLock(自旋鎖),實際上,我們還可以將任務分成多塊,由多個線程一起執行,最后合并多個線程的結果,如:求1到100的和,我們分10個線程,分別求1~10,......,90~100的和,然后合并十個線程的結果。還有就是使用線程安全集合,可參加第二天的文章。其實Task的同步機制做已經很好了,如果有特殊業務需求,有線程同步問題,大家可一起交流~~

?

?二、Task和線程池之間的抉擇

  我們要說的task的知識也說的差不多了,接下來我們開始站在理論上了解下“線程池”和“任務”之間的關系,我們要做到知其然,還要知其所以然。不管是說線程還是任務,我們都不可避免的要討論下線程池,然而在.net 4.0以后,線程池引擎考慮了未來的擴展性,已經充分利用多核微處理器架構,只要在可能的情況下,我們應該盡量使用task,而不是線程池。

?  這里簡要的分析下CLR線程池,其實線程池中有一個叫做“全局隊列”的概念,每一次我們使用QueueUserWorkItem的使用都會產生一個“工作項”,然后“工作項”進入“全局隊列”進行排隊,最后線程池中的的工作線程以FIFO(First Input First Output)的形式取出,這里值得一提的是在.net 4.0之后“全局隊列”采用了無鎖算法,相比以前版本鎖定“全局隊列”帶來的性能瓶頸有了很大的改觀。那么任務委托的線程池不光有“全局隊列”,而且每一個工作線程都有”局部隊列“。我們的第一反應肯定就是“局部隊列“有什么好處呢?這里暫且不說,我們先來看一下線程池中的任務分配,如下圖:

線程池的工作方式大致如下,線程池的最小線程數是6,線程1~3正在執行任務1~3,當有新的任務時,就會向線程池請求新的線程,線程池會將空閑線程分配出去,當線程不足時,線程池就會創建新的線程來執行任務,直到線程池達到最大線程數(線程池滿)。總的來說,只有有任務就會分配一個線程去執行,當FIFO十分頻繁時,會造成很大的線程管理開銷。

  下面我們來看一下task中是怎么做的,當我們new一個task的時候“工作項”就會進去”全局隊列”,如果我們的task執行的非常快,那么“全局隊列“就會FIFO的非常頻繁,那么有什么辦法緩解呢?當我們的task在嵌套的場景下,“局部隊列”就要產生效果了,比如我們一個task里面有3個task,那么這3個task就會存在于“局部隊列”中,如下圖的任務一,里面有三個任務要執行,也就是產生了所謂的"局部隊列",當任務三的線程執行完成時,就會從任務一種的隊列中以FIFO的形式"竊取"任務執行,從而減少了線程管理的開銷。這就相當于,有兩個人,一個人干完了分配給自己的所有活,而另一個人卻還有很多的活,閑的人應該接手點忙的人的活,一起快速完成。

  從上面種種情況我們看到,這些分流和負載都是普通ThreadPool.QueueUserWorkItem所不能辦到的,所以說在.net 4.0之后,我們盡可能的使用TPL,拋棄ThreadPool。

?

這是5天玩轉C#并行和多線程編程系列的最后一篇了,當然還有很多東西沒說到,如果真的想要玩轉多線程,還是要多多努力學習的。大家在學習過程中有什么問題可以一起交流~~

?

如果大家感覺我的博文對大家有幫助,請推薦支持一把,給我寫作的動力。

?

?作者:雲霏霏

?博客地址:http://www.cnblogs.com/yunfeifei/

?聲明:本博客原創文字只代表本人工作中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關系。非商業,未授權,貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

轉載于:https://www.cnblogs.com/Jeely/p/10999284.html

總結

以上是生活随笔為你收集整理的5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色5566| 一区二区三区中文字幕 | 欧美在线xxxx | 男女男网站 | 成人7777 | 国产一级二级三级 | 91精品国产91久久久 | 人妻洗澡被强公日日澡 | 日韩国产精品一区二区三区 | 日本一本久久 | 91女神在线 | 一区二区在线看 | 深夜福利电影 | 国产一区二区免费看 | 欧美热热 | 欧美色精品 | 一本色道久久综合亚洲精品图片 | 欧美一区二区三区久久久 | 黑人3p波多野结衣在线观看 | 久久久久香蕉 | 182tv午夜福利在线观看 | 污污免费观看 | 亚洲国产日韩精品 | 国产欧美精品一区二区 | 亚洲国产日韩av | 97免费视频观看 | 日本三级黄色大片 | 欧美三级一区二区三区 | 国产成人超碰人人澡人人澡 | 色窝在线 | 亚洲高清av| 成人3d动漫一区二区三区91 | 亚洲人妻一区二区 | 午夜不卡av免费 | 久久精品夜| 欧美人喂奶吃大乳 | 亚洲精品国产熟女久久久 | 伊人网综合视频 | 嫩草影院av | 久久综合激的五月天 | 精品在线观看一区 | 无遮挡无掩盖网站 | 日日操夜夜草 | 中国a毛片 | 日本在线网址 | 天天干狠狠插 | 天堂在线精品 | 亚洲视频黄色 | 欧美乱妇狂野欧美在线视频 | 中文字幕亚洲乱码熟女一区二区 | 欧美无极品| 亚洲欧美色图在线 | 日韩欧美中文字幕一区二区三区 | 欧美碰碰碰 | 亚洲一区av | 色哟哟免费视频 | 国产色在线,com | 97在线免费观看视频 | 中文字幕在线成人 | 日韩一级免费视频 | 人乳喂奶hd无中字 | 国产精品午夜电影 | 午夜有码 | 日日狠狠久久偷偷四色综合免费 | 精品一区二区免费视频 | 香蕉视频A| 九色91popny蝌蚪新疆 | 性视频一区 | 国产成人av一区二区三区 | 国产又爽又黄免费视频 | 黑人与日本少妇高潮 | 一级爱爱免费视频 | 少妇av一区二区 | 欧美成人综合一区 | 亚洲AV无码国产精品 | 全部免费毛片在线播放一个 | 亚洲天堂日本 | 欧美456 | 97国产精品人人爽人人做 | 在线91视频| 伊人影院视频 | 最近中文字幕mv免费高清在线 | 欧美夜夜操 | 丰满人妻一区二区三区在线 | 中文字幕校园春色 | www.日本在线视频 | v片在线观看 | 久久国产精品综合 | 久久天天东北熟女毛茸茸 | 久久精品一区二区 | 91 免费看片| 操女网站| 欧美精品久久久久久久自慰 | 黑人极品videos精品欧美裸 | 今天高清视频在线观看视频 | 久久视频中文字幕 | 黄色国产在线播放 | 精品视频网 | 国产一级视频在线观看 |