C#完成掌握線程池最年夜數並發線程。本站提示廣大學習愛好者:(C#完成掌握線程池最年夜數並發線程)文章只能為提供參考,不一定能成為您想要的結果。以下是C#完成掌握線程池最年夜數並發線程正文
1. 試驗目標:
應用線程池的時刻,有時刻須要斟酌辦事器的最年夜線程數量和法式最快履行一切營業邏輯的棄取。
並不是邏輯線程越多也好,並且新的邏輯線程必需會在線程池的期待隊列中期待 ,直到線程池中任務的線程履行終了,
才會有體系線程掏出期待隊列中的邏輯線程,停止CPU運算。
2. 處理成績:
<a>假如不斟酌辦事器現實可支撐的最年夜並行線程個數,法式一直往線程池請求新的邏輯線程,這個時刻我們可以發明CPU的應用率會赓續飙升,而且內存、收集帶寬占用也會跟著邏輯線程在CPU隊列中聚積,而赓續增年夜。
<b>假如我們想在主法式有200個http收集通信須要履行,若何每次輪回用10個線程並發處置10個收集http通信回話,下一次輪回只要在上一次輪回的10個線程都履行終了後才會履行下一次輪回,而且主法式監聽和期待200個http收集通信都在CPU線程池中履行終了後,才會加入主法式。
3. 完成邏輯:
我們經由過程兩個AutoResetEvent和線程監聽器Monitor,分離完成:
<a>wait_sync: 義務線程的 並發履行,每次輪回只處置最年夜10個線程分離對收集做http通信回話。而且以後輪回的10個線程都履行終了後,才會停止下一次輪回處置。
<b> wait_main: 主法式線程的監聽和期待,只要一切義務線程都履行終了後,主法式線程才會加入法式。
<c> list_Thread: 擔任記載每次輪回,CPU現實分派的體系線程的個數。和Monitor合營應用,Monitor.Enter(list_Thread)=占用同享線程資本的占用鎖,Monitor.Exit(list_Thread)釋放同享線程資本的占用鎖。
<d> n_total_thread: 合營wait_main應用,記載全體邏輯線程,曾經履行終了確當前總個數,用來斷定主線程能否還須要持續期待,照樣可以停止主法式運轉。
4. 重要代碼:
<a> 線程池掌握代碼,以下:
/// <summary> /// 多線程挪用WCF /// </summary> /// <param name="select">挪用WCF的方法,1=Restful,2=Tcp</param> /// <param name="num"></param> static void DoTest_MultiThread(string select, long num) { int n_max_thread = 10; // 設置並行最年夜為10個線程 int n_total_thread = 0; // 用來掌握:主法式的停止履行,當一切義務線程履行終了 ILog log_add = new LogHelper("Add_Thread"); ILog log_del = new LogHelper("Del_Thread"); ILog log_wait = new LogHelper("Wait_Thread"); ILog log_set = new LogHelper("Set_Thread"); ILog log_for = new LogHelper("For_Thread"); Console.Title = string.Format("挪用WCF的方法 => {0}, 挪用次數=> {1}" , select == "1" ? "Restful" : "Socket" , num); List<int> list_Thread = new List<int>(); System.Threading.AutoResetEvent wait_sync = new System.Threading.AutoResetEvent(false); // 用來掌握:並發最年夜個數線程=n_max_thread System.Threading.AutoResetEvent wait_main = new System.Threading.AutoResetEvent(false); // 用來掌握:主法式的停止履行,當一切義務線程履行終了 DateTime date_step = DateTime.Now; for (long i = 0; i < num; i++) { Num_Query_Static++; if (i >0 && (i+1-1) % n_max_thread == 0) // -1 表現第max個線程還沒有開端 { //log_wait.Info(string.Format("thread n= {0},for i= {1}", dic_Thread.Count, i + 1)); wait_sync.WaitOne(); // 每次並發10個線程,期待處置終了後,在發送下一次並發線程 } log_for.Info(string.Format("thread n= {0},for i= {1}", list_Thread.Count, i + 1)); System.Threading.ThreadPool.QueueUserWorkItem ((data) => { int id = System.Threading.Thread.CurrentThread.ManagedThreadId; System.Threading.Monitor.Enter(list_Thread); list_Thread.Add(id); System.Threading.Monitor.Exit(list_Thread); log_add.Info(string.Format("id={0}, count={1}", id, list_Thread.Count)); // 日記 if (select == "1") // Restful方法挪用 { Query_Htty(); } else { Query_Socket(); } n_total_thread += 1; if (list_Thread.Count == (n_max_thread) || n_total_thread == num) { list_Thread.Clear(); //log_set.Info(string.Format("thread n= {0},for i= {1}", dic_Thread.Count, i + 1)); //wait_sync.Set(); if (n_total_thread != num) { wait_sync.Set(); // 義務線程,持續履行 } else { wait_main.Set(); // 主法式線程,持續履行 } } }, list_Thread); } wait_main.WaitOne(); Console.WriteLine(string.Format("總測試{0}次,總耗時{1}, 均勻耗時{2}" , num , (DateTime.Now - date_step).ToString() , (DateTime.Now - date_step).TotalMilliseconds / num)); Query_Thread(); }
<b> WCF後台辦事代碼
private static ILog log = new LogHelper("SeqService"); // 日記 private static Dictionary<int, DateTime> dic_thread = new Dictionary<int, DateTime>(); // 線程列表 private static long Num = 0; // 線程個數 private static object lock_Num = 0; // 同享數據-鎖 /// <summary> /// 在線請求流水號 /// </summary> /// <returns></returns> [WebGet(UriTemplate = "GetSeqNum/Json", ResponseFormat = WebMessageFormat.Json)] public string GetSeqNumber() { lock (lock_Num) { Num++; int id_thread = System.Threading.Thread.CurrentThread.ManagedThreadId; DateTime now = DateTime.Now; if (!dic_thread.TryGetValue(id_thread, out now)) { dic_thread.Add(id_thread, DateTime.Now); } } string ret = DateTime.Now.ToString("yyyyMMdd") + Num.ToString(new string('0', 9)); log.Info(string.Format("{0}, Thread={1}/{2}", ret, System.Threading.Thread.CurrentThread.ManagedThreadId, dic_thread.Count)); return ret; }
5. 試驗成果
1. 10000個WCF收集http要求,CPU分紅每次10個(10可以按需求調劑)線程並發履行,而且主法式在一切要求都履行終了後,才加入主法式。
1. 前端日記:LogFile\Add_Thread\Info
2. WCF日記:LogFile\SeqService\Info