<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
當我們提及多執行緒的時候會想到thread和threadpool,這都是非同步操作,threadpool其實就是thread的集合,具有很多優勢,不過在任務多的時候全域性佇列會存在競爭而消耗資源。
thread預設為前臺執行緒,主程式必須等執行緒跑完才會關閉,而threadpool相反。
總結:threadpool確實比thread效能優,但是兩者都沒有很好的api區控制,如果執行緒執行無響應就只能等待結束,從而誕生了task任務。
task簡單地看就是任務,那和thread有什麼區別呢?
Task的背後的實現也是使用了執行緒池執行緒,但它的效能優於ThreadPoll,因為它使用的不是執行緒池的全域性佇列,而是使用的本地佇列,使執行緒之間的資源競爭減少。
同時Task提供了豐富的API來管理執行緒、控制。
但是相對前面的兩種耗記憶體,Task依賴於CPU對於多核的CPU效能遠超前兩者,單核的CPU三者的效能沒什麼差別。
使用new建立不會執行,必須等到start啟動之後才執行。
public void test() { var testTask = new Task(() => { Console.WriteLine("task start"); }); testTask.Start(); var factoryTeak = Task.Factory.StartNew(() => { Console.WriteLine("factory task start"); }); }
var testTask = new Task(() => { Console.WriteLine("task start"); System.Threading.Thread.Sleep(2000); }); Console.WriteLine(testTask.Status); testTask.Start(); Console.WriteLine(testTask.Status); Console.WriteLine(testTask.Status); testTask.Wait(); Console.WriteLine(testTask.Status); Console.WriteLine(testTask.Status);
輸出結果:
Created
task start
Running
Running
RanToCompletion
RanToCompletion
可以看出task確實是非同步執行,並且wait很好地控制了task。
var testTask = new Task(() => { Console.WriteLine("task start"); System.Threading.Thread.Sleep(2000); }); testTask.Start(); testTask.Wait();
var testTask = new Task(() => { Console.WriteLine("task start"); System.Threading.Thread.Sleep(2000); }); testTask.Start(); var factoryTeak = Task.Factory.StartNew(() => { Console.WriteLine("factory task start"); }); Task.WaitAll(testTask, factoryTeak); Console.WriteLine("end");
var testTask = new Task(() => { Console.WriteLine("task start"); System.Threading.Thread.Sleep(2000); }); testTask.Start(); var factoryTeak = Task.Factory.StartNew(() => { Console.WriteLine("factory task start"); }); Task.WaitAny(testTask, factoryTeak); Console.WriteLine("end");
通過wait()對單個task進行等待,Task.waitall()對多個task進行等待,waitany()執行任意一個task就往下繼續執行。
var testTask = new Task(() => { Console.WriteLine("task start"); System.Threading.Thread.Sleep(2000); }); testTask.Start(); var resultTest = testTask.ContinueWith<string>((Task) => { Console.WriteLine("testTask end"); return "end"; }); Console.WriteLine(resultTest.Result);
首先建立一個取消task的令牌的範例,在不啟動task直接取消:
var tokenSource = new CancellationTokenSource();//建立取消task範例 var testTask = new Task(() => { for (int i = 0; i < 6; i++) { System.Threading.Thread.Sleep(1000); } },tokenSource.Token); Console.WriteLine(testTask.Status); tokenSource.Token.Register(()=> { Console.WriteLine("task is to cancel"); }); tokenSource.Cancel(); Console.WriteLine(testTask.Status);
輸出結果:
Created
task is to cancel
Canceled
如果task啟動了真的取消了task?
var tokenSource = new CancellationTokenSource();//建立取消task範例 var testTask = new Task(() => { for (int i = 0; i <6; i++) { System.Threading.Thread.Sleep(1000); } },tokenSource.Token); Console.WriteLine(testTask.Status); testTask.Start(); Console.WriteLine(testTask.Status); tokenSource.Token.Register(()=> { Console.WriteLine("task is to cancel"); }); tokenSource.Cancel(); Console.WriteLine(testTask.Status); for (int i = 0; i < 10; i++) { System.Threading.Thread.Sleep(1000); Console.WriteLine(testTask.Status); }
輸出結果:
Created
WaitingToRun
task is to cancel
Running
Running
Running
Running
Running
Running
RanToCompletion
RanToCompletion
RanToCompletion
RanToCompletion
RanToCompletion
可以看出其實並沒有取消task,此時task還在繼續跑。
var parentTask = new Task(()=> { var childTask = new Task(() =>{ System.Threading.Thread.Sleep(2000); Console.WriteLine("childTask to start"); }); childTask.Start(); Console.WriteLine("parentTask to start"); }); parentTask.Start(); parentTask.Wait(); Console.WriteLine("end");
此時為普通關聯,父task和子task沒影響
var parentTask = new Task(()=> { var childTask = new Task(() =>{ System.Threading.Thread.Sleep(2000); Console.WriteLine("childTask to start"); }, TaskCreationOptions.AttachedToParent); childTask.Start(); Console.WriteLine("parentTask to start"); } ); parentTask.Start(); parentTask.Wait(); Console.WriteLine("end");
此時為父task和子task關聯,wait會一直等待父子task執行完。
我們可以設定最大等待時間,如果超過了等待時間,就不再等待,下面我們來修改程式碼,設定最大等待時間為5秒(專案中可以根據實際情況設定),如果超過5秒就輸出哪個任務出錯了
舉例來說Parallel.for和Parallel.foreach是執行緒不安全的,有可能達不到你的預期,此時就需要加鎖來解決此問題,我們可以加lock和spinlock(自旋鎖)來解決
SpinLock slock = new SpinLock(false); var testLock= new object(); long sum1 = 0; long sum2 = 0; long sum3 = 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); } }); Parallel.For(0, 100000, i => { lock(testLock) { sum3 += i; }; }); Console.WriteLine("Num1的值為:{0}", sum1); Console.WriteLine("Num2的值為:{0}", sum2); Console.WriteLine("Num3的值為:{0}", sum3);
輸出結果:
Num1的值為:1660913202
Num2的值為:4999950000
Num3的值為:4999950000
Num1的值為:2754493646
Num2的值為:4999950000
Num3的值為:4999950000
Num1的值為:4999950000
Num2的值為:4999950000
Num3的值為:4999950000
最後看看threadpoll和task的結構圖:
threadpool:
task:
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45