日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C#多線程,論多核時(shí)代愛恨情仇

博客前言

為什么要學(xué)習(xí)多線程?

  • 2010年1月21日是10年某市公務(wù)員考試的報(bào)名截止日。因從下午2點(diǎn)開始,用于報(bào)名的北京市人事考試網(wǎng)癱瘓,原定于昨天下午5點(diǎn)截止的報(bào)名時(shí)間延遲至今天上午11點(diǎn)。

  • 2011年3月11日下午5時(shí)(北京時(shí)間12日早9點(diǎn)),蘋果發(fā)布新一代的平板電腦產(chǎn)品iPad 2,配備了A5.1Ghz雙核處理器,這寓意著平板電腦和筆記本一同進(jìn)入"多核時(shí)代"。

  • 同年6月18日,國內(nèi)著名B2C---京東在周年慶典之際舉行了"隆重"的大規(guī)模的促銷活動(dòng),搶購隨之而來,訂單擠爆京東 限時(shí)達(dá)臨時(shí)取消。 昨天有消費(fèi)者反映,由于點(diǎn)擊量過大,18日早上京東商城網(wǎng)站一度癱瘓。一位消費(fèi)者說:“18日凌晨1點(diǎn)開始就登不上京東商城?!眲?qiáng)東也表示:由于流量多 次超過4個(gè)G,服務(wù)器運(yùn)行緩慢。 昨天,京東商城官網(wǎng)發(fā)布公告稱,“‘618’活動(dòng)異?;鸨矣脩粝聠嗡俣瓤涨?,致使部分用戶已購訂單顯示出現(xiàn)延遲,用戶在一段時(shí)間內(nèi)無法在‘我的京東’中 查詢到自己的訂單。目前已購訂單顯示延遲的問題已得到有效解決,對(duì)此給您帶來的不便,我們深表歉意?!?/p>

  • 2015年05月05日登錄風(fēng)信子網(wǎng)上商城發(fā)現(xiàn),首頁除了廣告和相關(guān)消息外,只有“注冊(cè)賬號(hào)獲取更多優(yōu)惠”這唯一一個(gè)按鈕,沒有商品展示,沒有產(chǎn) 品搜索,不能網(wǎng)上下單,甚至連進(jìn)入商城的按鈕也沒有。風(fēng)信子南沙跨境商品直購體驗(yàn)中心相關(guān)負(fù)責(zé)人表示,這主要是因?yàn)轭A(yù)約的人數(shù)太多,截至五一,預(yù)約人數(shù)已 超過十萬,太多人頻繁登陸,導(dǎo)致網(wǎng)店服務(wù)器癱瘓,目前技術(shù)人員還在努力維修中。該負(fù)責(zé)人介紹,體驗(yàn)中心的網(wǎng)站目前正在調(diào)試,“網(wǎng)站目前的作用主要是給市民 預(yù)約和提前注冊(cè),通過網(wǎng)絡(luò)注冊(cè)的市民不用在現(xiàn)場(chǎng)驗(yàn)證身份證等信息,可以提高購買效率。”

下面通過一些實(shí)例來認(rèn)識(shí)一下多線程和讓大家知道為什么要學(xué)習(xí)多線程。

寫在前面

老板只有兩種,好的和壞的。好的老板只跟你談錢,壞的老板只跟你談理想。

v模擬場(chǎng)景

假設(shè)后臺(tái)有個(gè)monitor時(shí)事的在監(jiān)測(cè)訂單,且可以發(fā)現(xiàn)訂單然后處理訂單,每次(1次/S)可以處理1千個(gè)訂單,需要向倉庫系統(tǒng)發(fā)出指令,讓他們負(fù)責(zé)配送發(fā)貨。那么我們來寫一個(gè)EmulationSystem(模擬系統(tǒng))

JobHelper因?yàn)槲覀冎皇菫榱四M一個(gè)環(huán)境,所以它是這樣的。

  
 
  1. //------------------------------------------------------------------------------ 
  2. //  
  3. //     Copyright (C) 2015-2016 All Rights Reserved 
  4. //     原博文地址: http://www.cnblogs.com/toutou/ 
  5. //   
  6. //------------------------------------------------------------------------------ 
  7. namespace CNBlogs.Common.Shared 
  8.     using System.Threading; 
  9.     ///  
  10.     /// Job helper 
  11.     ///  
  12.     public class JobHelper 
  13.     { 
  14.         ///  
  15.     /// Get job total count 
  16.         ///  
  17.     ///  
  18.     public int GetJobCount() 
  19.         { 
  20.             // 我們的側(cè)重點(diǎn)是多線程,所以我們就模擬每次有1千個(gè)訂單,而模擬,所以我們不關(guān)心其他的。只要訂單數(shù)量。 
  21.     return 1000; 
  22.         } 
  23.         ///  
  24.     /// Submit job 
  25.         ///  
  26.     /// For job id 
  27.     /// Submit job status 
  28.     public bool SubmitJob(int jobId) 
  29.         { 
  30.             // 假設(shè)針對(duì)每個(gè)訂單向后臺(tái)發(fā)送任務(wù)需要1秒,而且每個(gè)訂單都能成功發(fā)送 
  31.             Thread.Sleep(1000); 
  32.             return true; 
  33.         } 
  34.     } 

背景我們也交待完了,現(xiàn)在需要來得到這些訂單信息以后,向倉庫submit這些訂單。

v實(shí)戰(zhàn)演習(xí)

根據(jù)這種背景,我們可以有很多處理的辦法。

  • 傳統(tǒng)辦法:

    (開啟無腦模式:未使用多線程)

    代碼正文:

        
       
    1. //------------------------------------------------------------------------------ 
    2. //  
    3. //     Copyright (C) 2015-2016 All Rights Reserved 
    4. //     原博文地址: http://www.cnblogs.com/toutou/ 
    5. //   
    6. //------------------------------------------------------------------------------ 
    7. namespace CNBlogs.EmulationSystem 
    8.     using System; 
    9.     using System.Threading; 
    10.     using CNBlogs.Common.Shared; 
    11.     class Runner 
    12.     { 
    13.         ///  
    14.                 /// Job helper 
    15.         ///  
    16.                 private static JobHelper jobHelper = new JobHelper(); 
    17.         ///  
    18.                 /// Runner lock 
    19.         ///  
    20.                 private static Mutex mutex; 
    21.         static void Main(string[] args) 
    22.         { 
    23.             // 記錄開始處理的時(shí)間 
    24.             DateTime paddingTime = DateTime.Now.ToLocalTime(); 
    25.             int orderCount = jobHelper.GetJobCount(); 
    26.             // 用一個(gè)指示調(diào)用線程是否應(yīng)擁有互斥體的初始所屬權(quán)的布爾值來初始化 Mutex 類的新實(shí)例。 
    27.             // 當(dāng)前進(jìn)程只能啟動(dòng)一次 
    28.             mutex = new Mutex(false, "CNBlogs.EmulationSystem"); 
    29.             if (!mutex.WaitOne(0, false)) 
    30.             { 
    31.                 Console.Out.WriteLine("Monitor already running..."); 
    32.                 return; 
    33.             } 
    34.             for (int i = 0; i < orderCount; i++) 
    35.             { 
    36.                 // 假設(shè)i就是job id 
    37.                 jobHelper.SubmitJob(i); 
    38.             } 
    39.             // 記錄處理完成的時(shí)間 
    40.             DateTime completeTime = DateTime.Now.ToLocalTime(); 
    41.             var minutes = (completeTime - paddingTime).TotalSeconds; 
    42.             Console.WriteLine(string.Format("處理{0}個(gè)訂單,花費(fèi)時(shí)間{1}秒", orderCount, minutes)); 
    43.         } 
    44.     } 

    PS:現(xiàn)在的這些個(gè)電商,動(dòng)不動(dòng)來個(gè)什么周年慶店慶什么雙11雙12的一頓突突,搞得咱這些老百姓就全部蜂擁而上,顯然如果用傳統(tǒng)的方法雖然不會(huì)出錯(cuò),但是老板肯定會(huì)找你喝茶。在多核時(shí)代用這種方法也只能鐵不成鋼了。所以這個(gè)方法是絕對(duì)不可取的。

  • Task方法:

    如果有對(duì)Task不是很熟悉的園友可以在這里解開心謎。

    代碼正文:

         
       
    1. //------------------------------------------------------------------------------ 
    2. //  
    3. //     Copyright (C) 2015-2016 All Rights Reserved 
    4. //     原博文地址: http://www.cnblogs.com/toutou/ 
    5. //   
    6. //------------------------------------------------------------------------------ 
    7. namespace CNBlogs.EmulationSystem 
    8.     using System; 
    9.     using System.Collections.Generic; 
    10.     using System.Threading; 
    11.     using System.Threading.Tasks; 
    12.     using CNBlogs.Common.Shared; 
    13.     class Runner 
    14.     { 
    15.         ///  
    16.                 /// Job helper 
    17.         ///  
    18.                 private static JobHelper jobHelper = new JobHelper(); 
    19.         ///  
    20.                 /// Runner lock 
    21.         ///  
    22.                 private static Mutex mutex; 
    23.         static void Main(string[] args) 
    24.         { 
    25.             // 記錄開始處理的時(shí)間 
    26.             DateTime paddingTime = DateTime.Now.ToLocalTime(); 
    27.             int orderCount = jobHelper.GetJobCount(); 
    28.             // 用一個(gè)指示調(diào)用線程是否應(yīng)擁有互斥體的初始所屬權(quán)的布爾值來初始化 Mutex 類的新實(shí)例。 
    29.             // 當(dāng)前進(jìn)程只能啟動(dòng)一次 
    30.             mutex = new Mutex(false, "CNBlogs.EmulationSystem"); 
    31.             if (!mutex.WaitOne(0, false)) 
    32.             { 
    33.                 Console.Out.WriteLine("Monitor already running..."); 
    34.                 return; 
    35.             } 
    36.             var taskList = new List(); 
    37.             for (int i = 0; i < orderCount; i++) 
    38.             { 
    39.                 int temp=i; 
    40.                 taskList.Add(Task.Factory.StartNew(() => 
    41.                 { 
    42.                     // 假設(shè)i就是job id 
    43.                     jobHelper.SubmitJob(temp); 
    44.                 })); 
    45.             } 
    46.             // 等待所有task執(zhí)行完畢 
    47.             Task.WaitAll(taskList.ToArray()); 
    48.             // 記錄處理完成的時(shí)間 
    49.             DateTime completeTime = DateTime.Now.ToLocalTime(); 
    50.             var minutes = (completeTime - paddingTime).TotalSeconds; 
    51.             Console.WriteLine(string.Format("Complete: {0},cost {1} s", orderCount, minutes)); 
    52.         } 
    53.     } 

    代碼效果:

    相信分別從有TASK和沒有TASK的這兩次demo中,可以清楚的發(fā)現(xiàn)多線程處理這些頻繁交互能力的魅力。你會(huì)愛上這個(gè)方法。確實(shí)提高的效率。但是問題也隨之而來,一個(gè)進(jìn)程多線程的總數(shù)和大小是有要求的(這個(gè)取決于服務(wù)器的配置),不是任由我們肆意的開采的。如果訂單太多,我們不控制task那是會(huì)拉仇恨的。task需要控制。

  • Semaphore:

    如果有對(duì)Semaphore不是很熟悉的園友可以在這里解開心謎。

    代碼正文: 

        
       
    1. //------------------------------------------------------------------------------ 
    2. //  
    3. //     Copyright (C) 2015-2016 All Rights Reserved 
    4. //     原博文地址: http://www.cnblogs.com/toutou/ 
    5. //   
    6. //------------------------------------------------------------------------------ 
    7. namespace CNBlogs.EmulationSystem 
    8.     using System; 
    9.     using System.Collections.Generic; 
    10.     using System.Threading; 
    11.     using System.Threading.Tasks; 
    12.     using CNBlogs.Common.Shared; 
    13.     class Runner 
    14.     { 
    15.         ///  
    16.                 /// Job helper 
    17.         ///  
    18.                 private static JobHelper jobHelper = new JobHelper(); 
    19.         ///  
    20.                 /// The locker used to lock the semaphore and thread. 
    21.         ///  
    22.                 private static object lockerObj = new object(); 
    23.         ///  
    24.                 /// The semaphore limit the thread number of get latest test info 
    25.         ///  
    26.                 private static Semaphore semaphoreLimit; 
    27.         ///  
    28.                 /// Runner lock 
    29.         ///  
    30.                 private static Mutex mutex; 
    31.         static void Main(string[] args) 
    32.         { 
    33.             // 記錄開始處理的時(shí)間 
    34.             DateTime paddingTime = DateTime.Now.ToLocalTime(); 
    35.             int orderCount = jobHelper.GetJobCount(); 
    36.             // 用一個(gè)指示調(diào)用線程是否應(yīng)擁有互斥體的初始所屬權(quán)的布爾值來初始化 Mutex 類的新實(shí)例。 
    37.             // 當(dāng)前進(jìn)程只能啟動(dòng)一次 
    38.             mutex = new Mutex(false, "CNBlogs.EmulationSystem"); 
    39.             if (!mutex.WaitOne(0, false)) 
    40.             { 
    41.                 Console.Out.WriteLine("Monitor already running..."); 
    42.                 return; 
    43.             } 
    44.             // 假設(shè)我們的服務(wù)器一個(gè)進(jìn)程只能接受的大小=當(dāng)前線程大小*500 ps:500是設(shè)置信號(hào)量的最大值 
    45.                 int maxProcNumber = 500; 
    46.             using (semaphoreLimit = new Semaphore(0, maxProcNumber)) 
    47.             { 
    48.                 // 以指定的次數(shù)退出信號(hào)量并返回前一個(gè)計(jì)數(shù)。 
    49.                 semaphoreLimit.Release(maxProcNumber); 
    50.                 var taskList = new List(); 
    51.                 for (int i = 0; i < orderCount; i++) 
    52.                 { 
    53.                     int temp=i; 
    54.                     // 如果SubmitJob有IO或者其他容易因?yàn)闆_突而引起異常的話,這里需要加上lock 
    55.                     //lock (lockerObj) 
    56.                     //{ 
    57.                         semaphoreLimit.WaitOne(); 
    58.                         taskList.Add(Task.Factory.StartNew(() => 
    59.                         { 
    60.                             // 假設(shè)i就是job id 
    61.                             jobHelper.SubmitJob(temp); 
    62.                             // 退出信號(hào)量并返回前一個(gè)計(jì)數(shù)。 
    63.                             semaphoreLimit.Release(); 
    64.                         })); 
    65.                     //} 
    66.                 } 
    67.                 // 等待所有task執(zhí)行完畢 
    68.                 Task.WaitAll(taskList.ToArray()); 
    69.             } 
    70.             // 記錄處理完成的時(shí)間 
    71.             DateTime completeTime = DateTime.Now.ToLocalTime(); 
    72.             var minutes = (completeTime - paddingTime).TotalSeconds; 
    73.             Console.WriteLine(string.Format("Complete: {0},cost {1} s", orderCount, minutes)); 
    74.         } 
    75.     } 

    代碼效果:

v博客總結(jié)

多線程路還很長...


當(dāng)前標(biāo)題:C#多線程,論多核時(shí)代愛恨情仇
鏈接分享:http://www.dlmjj.cn/article/ccsgjge.html