C# 多執行緒ManualResetEvent、等待所有執行緒
需求:成員A可能有幾十個,我需要更新所有的A,然後根據A的資料,去更新成員B。
解決方案:思路是想通過多執行緒更新所有的A,然後通過等待執行緒來確定所有的A是否都更新完,最後更新B。
Member B = ....;//B成員的model IList<Member> list = ......;//查出所有的A成員,裝進list裡。 ManualResetEvent[] manualEvents = new ManualResetEvent[list.Count]; //更新所有的A成員 for (int i = 0; i < list.Count; i++) { manualEvents[i]= new ManualResetEvent(false);//初始化的ManualResetEvent必須是false model = new te();//目前我只知道此處只能傳一個引數,所以為了傳遞多個引數,我寫了個model,然後把要引數都放進model裡 model.MRevent = manualEvents[i]; model.member = list[i];//此處是我處理資料需要的引數,把成員的model傳進去 ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateMember), model); }//等待所有執行緒執行完畢 WaitHandle.WaitAll(manualEvents); //更新B成員 model = new te(); model.member = B; model.MRevent = new ManualResetEvent(false); UpdateMember(model);
處理資料的方法
public void UpdateMember(object tsmodel) { te stateInfo = (te)tsmodel; Member member = stateInfo.member;//中間為處理資料更新成員資料...... stateInfo.MRevent.Set(); //將事件狀態設定為終止狀態,允許一個或多個等待執行緒繼續(我個人理解是呼叫此方法,及為該執行緒結束,ManualResetEvent應該變成true) }
新建立的model
public class te { public Member member{ get; set; } public ManualResetEvent MRevent { get; set; }//小於64執行緒的時候使用 public MutipleThreadResetEvent MTRevent { get; set; }//大於64執行緒的時候使用 }
此處出現了新問題:
當執行緒大於64條時,會報錯。應該是WaitHandle.WaitAll(manualEvents);這等待的執行緒數不能大於64。
錯誤資訊:waithandles 的數目必須少於或等於 64 個。
原理:封裝一個ManualResetEvent物件,一個計數器current,提供SetOne和WaitAll方法;
主執行緒呼叫WaitAll方法使ManualResetEvent物件等待喚醒訊號;
各個子執行緒呼叫setOne方法 ,setOne每執行一次current減1,直到current等於0時表示所有子執行緒執行完畢 ,呼叫ManualResetEvent的set方法,這時主執行緒可以執行WaitAll之後的步驟。
目標:減少ManualResetEvent物件的大量產生和使用的簡單性。
/******************************************************************************** * Copyright © 2001 - 2010Comit. All Rights Reserved. * 檔案:MutipleThreadResetEvent.cs * 作者:楊柳 * 日期:2010年11月13日 * 描述:封裝 ManualResetEvent ,該類允許一次等待N(N>64)個事件執行完畢 * * 解決問題:WaitHandle.WaitAll(evetlist)方法最大隻能等待64個ManualResetEvent事件 * *********************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace TestMutipleThreadRestEvent { /// <summary> /// 封裝ManualResetEvent /// </summary> public class MutipleThreadResetEvent : IDisposable { private readonly ManualResetEvent done; private readonly int total; private long current; /// <summary> /// 建構函式 /// </summary> /// <param name="total">需要等待執行的執行緒總數</param> public MutipleThreadResetEvent(int total) { this.total = total; current = total; done = new ManualResetEvent(false); } /// <summary> /// 喚醒一個等待的執行緒 /// </summary> public void SetOne() { // Interlocked 原子操作類 ,此處將計數器減1 if (Interlocked.Decrement(ref current) == 0) { //當所以等待執行緒執行完畢時,喚醒等待的執行緒 done.Set(); } } /// <summary> /// 等待所以執行緒執行完畢 /// </summary> public void WaitAll() { done.WaitOne(); } /// <summary> /// 釋放物件佔用的空間 /// </summary> public void Dispose() { ((IDisposable)done).Dispose(); } } }
本質就是隻通過1個ManualResetEvent 物件就可以實現同步N(N可以大於64)個執行緒
修改後的方法:(黃色熒光筆的都是改動的程式碼)
Member B = ....;//B成員的model IList<Member> list = ......;//查出所有的A成員,裝進list裡。 //更所有A成員 using (var countdown = new MutipleThreadResetEvent(list.Count)) { for (int i = 0; i < list.Count; i++) { model = new te(); model.MTRevent = countdown; model.member = list[i]; //開啟N個執行緒,傳遞MutipleThreadResetEvent物件給子執行緒 ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateMember), model); } //等待所有執行緒執行完畢 countdown.WaitAll(); } //更新B成員 using (var countdown = new MutipleThreadResetEvent(1)) { model = new te(); model.MTRevent = countdown; model.member = B; //開啟N個執行緒,傳遞MutipleThreadResetEvent物件給子執行緒 ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateMember), model); //等待所有執行緒執行完畢 countdown.WaitAll(); }
處理資料的方法需要小改一下:
public void UpdateMember(object tsmodel) { te stateInfo = (te)tsmodel; Member member = stateInfo.member; //中間為處理資料更新成員資料 ...... stateInfo.MTRevent.SetOne();//此處呼叫封裝的方法 }
此時,大於64條執行緒的可以使用了。
相關推薦
C# 多執行緒ManualResetEvent、等待所有執行緒
需求:成員A可能有幾十個,我需要更新所有的A,然後根據A的資料,去更新成員B。 解決方案:思路是想通過多執行緒更新所有的A,然後通過等待執行緒來確定所有的A是否都更新完,最後更新B。 Member B = ....;//B成員的model IList<Member> list = .
Java多執行緒等待所有執行緒結束(CountDownLatch/CyclicBarrier)
本文主要是參考官方文件做一學習用途。 官方連結: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html http://docs.oracle.com/javase/1.5.0/docs/a
Linux執行緒---執行緒建立、等待、分離、優先順序
建立執行緒,等待執行緒終止 #include <stdio.h> #include <pthread.h> #include <stdlib.h> void f(void) { for(int i=0; i&l
java中等待所有執行緒都執行結束
看過之後在想java中有很大的靈活性,應該有更多的方式可以做這件事。 這個事情的場景是這樣的:許多執行緒並行的計算一堆問題,然後每個計算存在一個佇列,在主執行緒要等待所有計算結果完成後排序並展示出來。這樣的問題其實很常見。 1. 使用join。這種方式其實並不
自定義執行緒池、內建執行緒池.md
自定義簡單執行緒池 python執行緒是可以重複利用的,如果呼叫的時候每次都建立一個執行緒,則太浪費資源了 我把多執行緒比作服務員,每次有客人來的時候,都分配一個專門的服務員去服務; 當客人走了之後,服務員回到空閒狀態,繼續等待新的客人 import threa
top 執行一次、顯示所有程序資訊
1、執行一次 top命令會動態顯示資訊,若需要靜態的,比如只執行一次,或者只需要關於CPU的分析的那幾行,則使用代以下引數的命令: top -n 1 top執行一次,這樣便可以很方便的取出資訊,比如把這個資訊存到一個檔案中。 top -n 1 | head -n 5
[C++]多個物件構造、析構、構造和析構的順序
#include <iostream>//多個物件構造和析構//1)當類中有成員變數是其它類的物件時,首先呼叫成員變數的建構函式,呼叫順序與宣告順序相同;//之後呼叫自身類的建構函式//2)解構函式的呼叫順序與對應的建構函式呼叫順序相反////2、類成員中若有const修飾,必須在物件初始化的時候
使用執行緒池時讓所有執行緒都執行完再進行下一步
我們知道,當不使用執行緒池時,想讓A執行緒在B執行緒執行完之後執行,需要在A中的某個呼叫處,呼叫B.join,但如果使用jdk1.5以後提供的執行緒池ExecutorService,這個就用不上了,用了會出同步問題,其實這個場景應該是很常見的吧,比如你用多執行緒併發執
C#多執行緒基礎(多執行緒的優先順序、狀態、同步)
一、關於多執行緒的優先順序、狀態、同步指令碼如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System
C# 多執行緒學習系列四之取消、超時子執行緒操作
1、簡介 雖然ThreadPool、Thread能開啟子執行緒將一些任務交給子執行緒去承擔,但是很多時候,因為某種原因,比如子執行緒發生異常、或者子執行緒的業務邏輯不符合我們的預期,那麼這個時候我們必須關閉它,而不是讓它繼續執行,消耗資源.讓CPU不在把時間和資源花在沒有意義的程式碼上.
c/c++ 多執行緒 等待一次性事件 packaged_task用法
多執行緒 等待一次性事件 packaged_task用法 背景:不是很明白,不知道為了解決什麼業務場景,感覺std::asynck可以優雅的搞定一切,一次等待性事件,為什麼還有個packaged_task。 用法:和std::async一樣,也能夠返回std::future,通過呼叫get_future方
c/c++ 多執行緒 等待一次性事件 std::promise用法
多執行緒 等待一次性事件 std::promise用法 背景:不是很明白,不知道為了解決什麼業務場景,感覺std::async可以優雅的搞定一切的一次等待性事件,為什麼還有個std::promise。 用法:和std::async一樣,也能夠返回std::future,通過呼叫get_future方法。也
c/c++ 多執行緒 多個執行緒等待同一個執行緒的一次性事件
多執行緒 多個執行緒等待一個執行緒的一次性事件 背景:從多個執行緒訪問同一個std::future,也就是多個執行緒都在等待同一個執行緒的結果,這時怎麼處理。 辦法:由於std::future只能被呼叫一次get方法,也就是隻能被某一個執行緒等待(同步)一次,不支援被多個執行緒等待。所以std::shar
C# 基礎(十四)C#單例模式:首先介紹 單執行緒、多執行緒、加鎖 單例模式。然後介紹單例模式的執行緒同步:多執行緒有序訪問共享記憶體。
一、簡介 本篇文章將介紹如何使用單例模式,也就是類的例項化,在整個專案的生命週期內,只例項化一次。在單例模式中,往往可以看到如SourceCode.cs:這樣的結構的。 SourceCode.cs: public class Singleton { private static
Java第十四天學習筆記~多執行緒(執行緒直接通訊---等待喚醒機制、多生產者多消費者問題、JDK1.5新特性、wait和sleep區別)
執行緒直接通訊示例 //資源 class Resource { String name; String sex; } //輸入 class Input implements Runnable { Resource r; Input(Resource r) { this.r=r;
GCD多執行緒之多工併發等待所有任務完成
在實際專案中我們經常會遇到,發出多個網路請求,然後等待所有結果都返回後,再進行下一步操作的需求。那麼GCD完美的解決了這個樣的需求。 第一種方式: //建立佇列組 dispatch_g
Windows10 VS2017 C++多執行緒傳參和等待執行緒結束
#include "pch.h" #include <iostream> #include <windows.h> using namespace std; typedef struct MyData { const char* str; }MYDATA;
【C++多執行緒程式設計學習(1)】-CPU個數、CPU核心數、CPU執行緒數
轉自:CPU個數、CPU核心數、CPU執行緒數(by kimsimple) CPU個數即CPU晶片個數。 CPU核心數是指物理上,也就是硬體上存在著幾個核心。比如,雙核就是包括2個相對獨立的CPU核心單元組,四核就包含4個相對獨立的CPU核心單元組。 CPU執行緒數是一
C++——多執行緒程式設計(二)std::mutex 執行緒同步、解決資源競爭問題
前言 執行緒同步 這裡的“同”不是同時、一起執行的意思,而是指協同、協助、互相配合。執行緒同步是指多個執行緒協同步調,按預定的先後次序進行執行。 執行緒A和B一塊配合,A執行到一定程度時要依靠B的某個結果,於是停下來,示意B執行;B依言執行,再將結果給A;
Objective-C多執行緒詳解(NSThread、NSOperation、GCD)
程序和執行緒 程式:一個由原始碼生成的可執行應用(比如qq,微信…) 程序:程序是指在系統中正在執行的一個應用程式。一個正在執行的程式可以看成一個程序,程序負責去向手機系統申請資源,同時將這些資源排程給我們的執行緒 執行緒:1個程序要想執行任務,必須得有執