第九节:深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)
一. 并行編程
1. 區(qū)分串行編程和串行編程
①. 串行編程:所謂的串行編程就是單線程的作用下,按順序執(zhí)行。(典型代表for循環(huán) 下面例子從1-100按順序執(zhí)行)
②. 并行編程:充分利用多核cpu的優(yōu)勢(shì),同時(shí)開(kāi)啟多個(gè)線程并行執(zhí)行。(典型代表Parallel.For循環(huán) 下面例子從1-100無(wú)序執(zhí)行)
?代碼實(shí)踐:
?
1 {2 //1. 串行 (從1-100按順序執(zhí)行)3 for (int i = 1; i < 100; i++)4 {5 Console.WriteLine(i);6 }7 //2. 并行 (從1-100無(wú)序執(zhí)行)8 Parallel.For(1, 100, (item) =>9 { 10 Console.WriteLine(item); 11 }); 12 }?
結(jié)論:串行的代碼按順序依次輸出,并行的代碼無(wú)順序輸出。
2. 深究Parallel類(lèi)中的方法 (For方法、ForEach方法、Invoke方法 這三個(gè)方法都是用來(lái)開(kāi)啟線程的)
(1). Invoke方法
a. 該方法的作用就是用來(lái)同時(shí)開(kāi)啟多個(gè)線程的。
b. 該方法有兩個(gè)重載,主要涉及到兩個(gè)參數(shù),用來(lái)配置最大并行數(shù)(即線程數(shù))和一個(gè)可變的Action委托數(shù)組(詳見(jiàn)源碼)。
案例一: 開(kāi)啟五個(gè)不同的線程調(diào)用五個(gè)方法
我們發(fā)現(xiàn)一個(gè)現(xiàn)象,主線程等著這五個(gè)子線程執(zhí)行完畢后才執(zhí)行,但是我們并沒(méi)有寫(xiě)線程等待的代碼,所以我們可以總結(jié):
①:并行計(jì)算,開(kāi)啟多個(gè)線程后,不需要再開(kāi)辟線程等待,直接是主線程完成后續(xù)操作。
②:而普通多線程執(zhí)行后,需要單獨(dú)再開(kāi)辟一個(gè)線程等待,然后主線程再執(zhí)行。
?
?代碼實(shí)踐:
?
1 { 2 Parallel.Invoke(() => this.TestThread("bct1") 3 , () => this.TestThread("bct2") 4 , () => this.TestThread("bct3") 5 , () => this.TestThread("bct4") 6 , () => this.TestThread("bct5") 7 ); 8 }案例二: 指定最大并行數(shù)進(jìn)行線程調(diào)用
我們發(fā)現(xiàn),五個(gè)任務(wù)中的四個(gè)任務(wù)同時(shí)由不同線程開(kāi)啟,當(dāng)其中一個(gè)任務(wù)結(jié)束時(shí),第五個(gè)任務(wù)開(kāi)啟,并由剛結(jié)束的任務(wù)的線程來(lái)執(zhí)行。
?
{//設(shè)置最大的線程并行數(shù)ParallelOptions p = new ParallelOptions();p.MaxDegreeOfParallelism = 4;Parallel.Invoke(p, () => this.TestThread("bct1"), () => this.TestThread("bct2"), () => this.TestThread("bct3"), () => this.TestThread("bct4"), () => this.TestThread("bct5"));}(2). For方法 (前兩個(gè)參數(shù)之間的差,代表任務(wù)的個(gè)數(shù))
這里介紹一個(gè)簡(jiǎn)單重載: public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);
fromInclusive:開(kāi)始索引(含).
toExclusive:結(jié)束索引(不含).
body:將為每個(gè)迭代調(diào)用一次的委托.
當(dāng)然該方法中的其他重載中也有很豐富的功能,比如也可以配置最大線程數(shù)。
代碼實(shí)踐:
1 {2 //案例一:前兩個(gè)參數(shù)之間的差,就為并行計(jì)算線程的個(gè)數(shù)3 {4 Parallel.For(5, 10, t =>5 {6 //這里的t分別為:5,6,7,8,9 五個(gè)數(shù)7 string name = string.Format("bct{0}", t);8 this.TestThread(name);9 }); 10 } 11 //案例二: 配置最大并行數(shù) 12 //結(jié)果:同時(shí)最多5個(gè)線程執(zhí)行,但是還是要執(zhí)行9個(gè)任務(wù),(6,7,8,9,10,11,12,13,14),后面四個(gè)任務(wù)等前面的執(zhí)行完后,再執(zhí)行 13 { 14 ParallelOptions po = new ParallelOptions() 15 { 16 MaxDegreeOfParallelism = 5 //表示最大線程數(shù)為5,后面即使配置超過(guò)5,也無(wú)效 17 }; 18 Parallel.For(6, 15, po, (t, state) => 19 { 20 string name = string.Format("bct{0}", t); 21 this.TestThread(name); 22 //state.Break(); //退出單次循環(huán)(沒(méi)看到實(shí)際作用) 23 // state.Stop(); //退出全部循環(huán)(沒(méi)看到實(shí)際作用) 24 //return; 25 }); 26 } 27 }?
(3). ForEach方法
這里也是介紹一個(gè)簡(jiǎn)單的重載:int數(shù)組中的個(gè)數(shù)代表需要進(jìn)行并行任務(wù)的個(gè)數(shù),但并不一定所有任務(wù)同時(shí)執(zhí)行,也不一定每個(gè)任務(wù)都是一個(gè)新線程執(zhí)行。
該方法當(dāng)然也可以配置最大并行數(shù)。
?代碼實(shí)踐:
?
{//數(shù)組里的個(gè)數(shù),就為并行進(jìn)行并行任務(wù)數(shù)Parallel.ForEach(new int[] { 3, 5, 44, 55, 100 }, t =>{//這里的t分別為:3, 5, 44, 55, 100五個(gè)數(shù)string name = string.Format("bct{0}", t);this.TestThread(name);} }?
?
二. 常見(jiàn)的編程模型
1.同步編程模型(SPM):單線線程、串行開(kāi)發(fā)模式。
2.異步編程模型(APM):xxxbegin、xxxend的模式。
3.基于事件的編程模型(EAP): xxAsync這樣的事件模式。 eg:WebClient。
4.基于Task的編程模型(TAP): APM和EAP都可以使用Task來(lái)實(shí)現(xiàn),微軟的初衷就是想通過(guò)Task大一統(tǒng)異步編程領(lǐng)域。
下面分享兩段代碼,不做深入研究了。
?
1 {2 FileStream fs = new FileStream(Environment.CurrentDirectory + "//1.txt", FileMode.Open);3 var bytes = new byte[fs.Length];4 var task = Task.Factory.FromAsync(fs.BeginRead, fs.EndRead, bytes, 0, bytes.Length, string.Empty);5 6 var nums = task.Result;7 8 Console.WriteLine(nums);9 } 10 { 11 FileStream fs = new FileStream(Environment.CurrentDirectory + "//1.txt", FileMode.Open); 12 13 var bytes = new byte[fs.Length]; 14 15 fs.BeginRead(bytes, 0, bytes.Length, (aysc) => 16 { 17 var nums = fs.EndRead(aysc); 18 19 Console.WriteLine(nums); 20 21 }, string.Empty); 22 23 Console.Read(); 24 }總結(jié)
以上是生活随笔為你收集整理的第九节:深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 第九节:委托和事件(1)(委托的发展历史
- 下一篇: “天际老奶奶”喊话B社总监Todd:让我