在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

多線程之線程池

汽車電子技術(shù) ? 來源:程序猿知秋 ? 作者:程序猿知秋 ? 2023-02-28 09:53 ? 次閱讀

圖片

線程池的基本概念

什么是線程池?

  • ** .NET Framework的ThreadPool類提供一個線程池**
  • “線程池”是可以用來在后臺執(zhí)行多個任務(wù)的線程集合
  • 線程池通常用于服務(wù)器應(yīng)用程序。 每個傳入請求都將分配給線程池中的一個線程,因此可以異步處理請求,而不會占用主線程,也不會延遲后續(xù)請求的處理
  • 一旦池中的某個線程完成任務(wù),它將返回到等待線程隊列中,等待被再次使用。 這種重用使應(yīng)用程序可以避免為每個任務(wù)創(chuàng)建新線程的開銷
  • 線程池通常具有最大線程數(shù)限制。 如果所有線程都繁忙,則額外的任務(wù)將放入隊列中,直到有線程可用時才能夠得到處理

為什么要用線程池?

  • 線程是非常消耗資源的,如果我們每次需要子線程來執(zhí)行任務(wù),就去創(chuàng)建一個新的線程,那當(dāng)我們執(zhí)行1千次1萬次甚至是100萬次的時候,那么電腦的資源消耗就非常嚴重,甚至承受不了
  • 線程池可以避免大量的創(chuàng)建和銷毀的開支,具有更好的性能和穩(wěn)定性
  • 開發(fā)人員把線程交給系統(tǒng)管理,可以集中精力處理其他任務(wù)

前臺線程&后臺線程

  • 前臺線程: 當(dāng)程序運行起來后,主線程已經(jīng)運行結(jié)束了,但是程序卻沒有停止,子線程依然在運行
  • 后臺線程: 只要主線程和所有的前臺線程執(zhí)行結(jié)束,就算后臺線程的任務(wù)還沒完成,也會強行打斷直接退出
  • 特點: 后臺適用于不太重要的任務(wù),即被中斷了也沒事的。 前臺線程適用于比較重要的任務(wù),必須等任務(wù)執(zhí)行完程序才能關(guān)閉
  • ThreadPool 線程池中的線程都是 后臺線程

線程池的使用

設(shè)置線程池大小

  • ThreadPool.SetMaxThreads (int workerThreads,int completionPortThreads)
  • ThreadPool.SetMinThreads (int workerThreads,int completionPortThreads)
  • 參數(shù)解析:
    • completionPortThreads:線程池中異步 I/O 線程的數(shù)目 (I/O 完成線程)
    • workerThreads:線程池中輔助線程的數(shù)目**(工作線程)**
  • 對于以上兩個參數(shù)的解釋,摘自網(wǎng)絡(luò)其它博客:
    • 主要用來完成 輸入和輸出的工作 ,在這種情況下, 計算機需要I/O設(shè)備完成輸入和輸出的任務(wù)。在處理過程中, CPU是不需要參與處理過程的此時正在運行的線程將處于等待狀態(tài)只有等任務(wù)完成后才會有事可做這樣就造成線程資源浪費的問題。為了解決這樣的問題,可以通過線程池來解決這樣的問題,讓線程池來管理線程

    • .NET中的一些API方法,通過APM(異步編程模式),內(nèi)部實現(xiàn)了ThreadPool.BindHandle方法。BeginXXX方法將用戶的回調(diào)委托送到某個設(shè)備驅(qū)動程序,然后返回線程池。

      當(dāng)做完成后,OS會通過IOCP提醒CLR它工作已經(jīng)完成,當(dāng)接收到通知后,I/O線程會醒來并且運行用戶的回調(diào)

    • 所以工作線程由開發(fā)人員調(diào)用, I/O線程由CLR調(diào)用 。所以通常情況下,開發(fā)者并不會直接用到它。因此可以認為, 工作者線程和I/O線程沒有區(qū)別,它們都是普通的線程但是CLR線程池中區(qū)分它們的目的是為了避免線程都去處理I/O回調(diào)而被耗盡,從而引發(fā)死鎖 。(設(shè)想,所有的工作者線程每一個都去等待I/O異步完成。)

    • 用來完成一些 計算的任務(wù) ,在任務(wù)執(zhí)行的過程中,需要 CPU不間斷地處理 ,所以,在工作者線程的執(zhí)行過程中,CPU和線程的資源是充分利用的

    • .NET中的術(shù)語工作者線程指的是任何線程而不是僅僅主線程

    • 工作者線程

    • I/O線程

啟動線程任務(wù)使用: QueueUserWorkItem()方法

  • static bool QueueUserWorkItem(WaitCallback callBack):參數(shù)為一個帶一個object類型參數(shù)的委托,最后返回bool值成功則返回true
class ThreadPoolTest
{
  static void Main()
  {
    Console.WriteLine("啟動多線程...");
    for(int i = 0; i <10; i++)
    {
      ThreadPool.QueueUserWorkItem( p => printStr("當(dāng)前線程") );
    }
    Console.WriteLine("結(jié)束多線程...");
    Console.ReadKey();
  }


  private static void printStr(string str)
  {
    Console.WriteLine("{0}是:{1}", str, Thread.CurrentThread.ManagedThreadId);
  }
}

輸出結(jié)果, 可以看到有很多線程ID是重復(fù)的,這就是線程池的強大之處了

啟動多線程...
結(jié)束多線程...
當(dāng)前線程是:8
當(dāng)前線程是:6
當(dāng)前線程是:10
當(dāng)前線程是:9
當(dāng)前線程是:7
當(dāng)前線程是:11
當(dāng)前線程是:12
當(dāng)前線程是:9
當(dāng)前線程是:6
當(dāng)前線程是:10

查看最大/最小線程數(shù) && 設(shè)置最大/最小線程數(shù)

class ThreadPoolTest
{
  static void Main()
  {
    // 獲取默認的線程池中的最大,最小線程數(shù)
    ThreadPool.GetMaxThreads(out int maxWorkerThreads, out int maxCompletionPortThreads);
    Console.WriteLine("最大線程數(shù),工作線程:{0}, IO線程數(shù):{1}", maxWorkerThreads, maxCompletionPortThreads);
    ThreadPool.GetMinThreads(out int minWorkerThreads, out int minCompletionPortThreads);
    Console.WriteLine("最小線程數(shù),工作線程:{0}, IO線程數(shù):{1}", minWorkerThreads, minCompletionPortThreads);


    // 重新設(shè)置最大、最小線程數(shù)
    ThreadPool.SetMaxThreads(10, 10);
    ThreadPool.SetMinThreads(3, 3);
    // 獲取默認的線程池中的最大,最小線程數(shù)
    ThreadPool.GetMaxThreads(out int newMaxWorkThread, out int newMaxIOThread);
    Console.WriteLine("重新設(shè)置后的最大線程數(shù),工作線程:{0}, IO線程數(shù):{1}", newMaxWorkThread, newMaxIOThread);
    ThreadPool.GetMinThreads(out int newMinWorkThread, out int newMinIOThread);
    Console.WriteLine("重新設(shè)置后的最小線程數(shù),工作線程:{0}, IO線程數(shù):{1}", newMinWorkThread, newMinIOThread);




    Console.WriteLine("啟動多線程...");
    for(int i = 0; i <10; i++)
    {
      ThreadPool.QueueUserWorkItem( p => printStr("當(dāng)前線程") );
    }
    Console.WriteLine("結(jié)束多線程...");
    Console.ReadKey();
  }


  private static void printStr(string str)
  {
    Console.WriteLine("{0}是:{1}", str, Thread.CurrentThread.ManagedThreadId);
  }
}

輸出結(jié)果

最大線程數(shù),工作線程:32767, IO線程數(shù):1000
最小線程數(shù),工作線程:8, IO線程數(shù):8
重新設(shè)置后的最大線程數(shù),工作線程:10, IO線程數(shù):10
重新設(shè)置后的最小線程數(shù),工作線程:3, IO線程數(shù):3
啟動多線程...
結(jié)束多線程...
當(dāng)前線程是:6
當(dāng)前線程是:9
當(dāng)前線程是:7
當(dāng)前線程是:8
當(dāng)前線程是:11
當(dāng)前線程是:10
當(dāng)前線程是:12
當(dāng)前線程是:11
當(dāng)前線程是:7
當(dāng)前線程是:9

ThreadPool.SetMaxThreads的默認值

  • 它取決于.NET框架版本,在2.0,3.0和4.0中進行了更改。 在2.0中它是核心數(shù)量的50倍。 在3.0(又名2.0 SP1)中,它是內(nèi)核數(shù)量的250倍,4.0根據(jù)位數(shù)和操作系統(tǒng)資源使其動態(tài)化。 默認 Max I / O完成線程是1000
  • 一般來說,它是非常的高,一個程序永遠不會接近

使用以上方法設(shè)置線程數(shù)據(jù)大小時需注意

  • 不能將最大工作線程數(shù)或 I/O 完成線程數(shù)設(shè)置為小于計算機上的處理器數(shù)的數(shù)字
  • 不能將最大工作線程數(shù)或 I/O 完成線程數(shù)設(shè)置為小于相應(yīng)最小工作線程數(shù)或 I/O 完成線程數(shù)的數(shù)字
  • 默認情況下,最小線程數(shù)設(shè)置為系統(tǒng)上的處理器數(shù)。 可以使用該方法 SetMinThreads 增加最小線程數(shù)。 但是,不必要地增加這些值可能導(dǎo)致性能問題。 如果在同一時間開始太多的任務(wù),則所有任務(wù)均可能會很慢。 在大多數(shù)情況下,線程池將使用自己的算法更好地分配線程。 將最小處理器減少到小于處理器數(shù)也會損害性能

查看系統(tǒng)cpu的處理數(shù)

圖片編輯

**線程等待 **

由于線程池中的線程都是后臺線程,當(dāng)主線程及所有前臺線程執(zhí)行完時,后臺線程就會被中斷,但如果我們希望 主線程等待 線程池執(zhí)行完成任務(wù)后再關(guān)閉程序 怎么辦呢?

需要使用到ManualResetEvent類

圖片編輯

**ManualResetEvent需要一個bool類型的參數(shù)來表示暫停和停止

**

class ThreadPoolTest2
{
  // 參數(shù)設(shè)置為false
  static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

  static void Main()
  {
    Console.WriteLine("啟動多線程...");
    ThreadPool.QueueUserWorkItem(p => printStr("當(dāng)前線程"));
    // 等待 線程池執(zhí)行任務(wù)完成
    manualResetEvent.WaitOne();
    Console.WriteLine("結(jié)束多線程...");
  }


  private static void printStr(string str)
  {
    Console.WriteLine("{0}是:{1}", str, Thread.CurrentThread.ManagedThreadId);
    // 設(shè)置為true
    manualResetEvent.Set();
  }
}

輸出結(jié)果

啟動多線程...
當(dāng)前線程是:6
結(jié)束多線程...

ManualResetEvent類的參數(shù)值執(zhí)行順序如下:

  • false-- WaitOne等待
  • true--WaitOne通過

注:一般情況下,不要阻塞線程池中的線程,因為寫代碼無意間造成的線程等待沒有釋放,一旦線程池線程耗盡就會形成死鎖

造成死鎖的案例: 設(shè)置了最大線程數(shù)是9,循環(huán)創(chuàng)建15個線程,意味著 后6個線程必然需要利用線程池中前面用過的線程, 但是由于前面創(chuàng)建的線程都直接讓阻塞了,沒有釋放,這時循環(huán)到第10個線程時由于沒有空閑線程,線程池沒法執(zhí)行就直接跳過了,主線程會繼續(xù)執(zhí)行后面的循環(huán),這樣也永遠不會 執(zhí)行 manualResetEvent.Set() 方法,最后就成死鎖了

private static void Test1()
{
  // 設(shè)置最大線程
  ThreadPool.SetMaxThreads(9, 9);
  // 設(shè)置最小線程
  ThreadPool.SetMinThreads(3, 3);
  ManualResetEvent manualResetEvent = new ManualResetEvent(false);
  for (int i = 0; i < 15; i++)
  {
    int k = i;
    ThreadPool.QueueUserWorkItem(p =>
    {
      Console.WriteLine(k);
      if (k < 10)
      {
        manualResetEvent.WaitOne();
      }
      else
      {
        // 設(shè)為true
        manualResetEvent.Set();
      }
    });
  }
  if (manualResetEvent.WaitOne())
  {
    Console.WriteLine("沒有死鎖。。。。。。。。。");
  }
  Console.WriteLine("結(jié)束。。。。。。。。。。");
}

輸出結(jié)果

1
0
2
3
4
5
6
7
8
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    9437

    瀏覽量

    86510
  • 應(yīng)用程序
    +關(guān)注

    關(guān)注

    38

    文章

    3305

    瀏覽量

    58213
  • 線程池
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    6947
收藏 人收藏

    評論

    相關(guān)推薦

    C語言線程的實現(xiàn)方案

    這是一個簡單小巧的C語言線程實現(xiàn),在 Github 上有 1.1K 的 star,很適合用來學(xué)習(xí) Linux 的多線程編程。
    的頭像 發(fā)表于 01-29 16:43 ?1645次閱讀

    跨平臺的線程組件--TP組件

    /銷毀代價是很高的。那么我們要怎么去設(shè)計多線程編程呢???答案:對于長駐的線程,我們可以創(chuàng)建獨立的線程去執(zhí)行。但是非長駐的線程,我們可以通過線程
    的頭像 發(fā)表于 04-06 15:39 ?968次閱讀

    多線程程之一: 問題提出

    多線程程之一 問題提出編寫一個耗時的單線程程序:  新建一個基于對話框的應(yīng)用程序SingleThread,在主對話框IDD_SINGLETHREAD_DIALOG添加一個按鈕,ID為
    發(fā)表于 10-22 11:41

    多線程程之線程間通訊

    多線程程之線程間通訊七、線程間通訊  一般而言,應(yīng)用程序中的一個次要線程總是為主線程執(zhí)行特
    發(fā)表于 10-22 11:43

    多線程程之線程的同步

    多線程程之線程的同步八、線程的同步  雖然多線程能給我們帶來好處,但是也有不少問題需要解決。例如,對于像磁盤驅(qū)動器這樣獨占性系統(tǒng)資源,
    發(fā)表于 10-22 11:43

    Delphi教程之多線程與數(shù)據(jù)庫

    Delphi教程之多線程與數(shù)據(jù)庫,很好的Delphi資料,快來下載學(xué)習(xí)吧。
    發(fā)表于 04-11 15:59 ?5次下載

    多線程好還是單線程好?單線程多線程的區(qū)別 優(yōu)缺點分析

    摘要:如今單線程多線程已經(jīng)得到普遍運用,那么到底多線程好還是單線程好呢?單線程多線程的區(qū)別又
    發(fā)表于 12-08 09:33 ?8.2w次閱讀

    mfc多線程編程實例及代碼,mfc多線程間通信介紹

    摘要:本文主要以MFC多線程為中心,分別對MFC多線程的實例、MFC多線程之間的通信展開的一系列研究,下面我們來看看原文。
    發(fā)表于 12-08 15:23 ?1.8w次閱讀
    mfc<b class='flag-5'>多線程</b>編程實例及代碼,mfc<b class='flag-5'>多線程</b>間通信介紹

    從CPU說起多線程以及線程

    從這篇開始將會開啟高性能、高并發(fā)系列,本篇是該系列的開篇,主要關(guān)注多線程以及線程。 一切要從CPU說起 你可能會有疑問,講多線程為什么要從CPU說起呢?原因很簡單,在這里沒有那些時髦
    的頭像 發(fā)表于 03-02 13:48 ?1998次閱讀

    PyQT5+OpenCV多線程協(xié)作演示

    學(xué)習(xí)多線程最典型的問題就是如何在多個線程之間傳遞消息與寫作,PyQT5的線程支持在不同線程之間傳遞信號觸發(fā)事件,實現(xiàn)多個線程之間的協(xié)助,完成
    的頭像 發(fā)表于 03-08 14:58 ?1439次閱讀

    Spring 的線程應(yīng)用

    我們在日常開發(fā)中,經(jīng)常跟多線程打交道,Spring 為我們提供了一個線程方便我們開發(fā),它就是 ThreadPoolTaskExecutor ,接下來我們就來聊聊 Spring 的線程
    的頭像 發(fā)表于 10-13 10:47 ?686次閱讀
    Spring 的<b class='flag-5'>線程</b><b class='flag-5'>池</b>應(yīng)用

    線程基本概念與原理

    、17、20等的新特性,簡化了多線程編程的實現(xiàn)。 提高性能與資源利用率 線程主要解決兩個問題:線程創(chuàng)建與銷毀的開銷以及線程競爭造成的性能瓶
    的頭像 發(fā)表于 11-10 10:24 ?640次閱讀

    什么是動態(tài)線程?動態(tài)線程的簡單實現(xiàn)思路

    因此,動態(tài)可監(jiān)控線程一種針對以上痛點開發(fā)的線程管理工具。主要可實現(xiàn)功能有:提供對 Spring 應(yīng)用內(nèi)線程
    的頭像 發(fā)表于 02-28 10:42 ?822次閱讀

    java實現(xiàn)多線程的幾種方式

    了多種實現(xiàn)多線程的方式,本文將詳細介紹以下幾種方式: 1.繼承Thread類 2.實現(xiàn)Runnable接口 3.Callable和Future 4.線程 5.Java 8中
    的頭像 發(fā)表于 03-14 16:55 ?859次閱讀

    Python中多線程和多進程的區(qū)別

    Python作為一種高級編程語言,提供了多種并發(fā)編程的方式,其中多線程與多進程是最常見的兩種方式之一。在本文中,我們將探討Python中多線程與多進程的概念、區(qū)別以及如何使用線程與進
    的頭像 發(fā)表于 10-23 11:48 ?631次閱讀
    Python中<b class='flag-5'>多線程</b>和多進程的區(qū)別
    主站蜘蛛池模板: 高颜值美女啪啪 | 欧美大全| 人人干视频 | 日韩色区| 色综合成人 | 最新仑乱免费视频 | 天天挨操 | 亚洲色图第一页 | 极品美女写真菠萝蜜视频 | 丁香综合在线 | 色男人在线 | 日韩欧美中文字幕在线视频 | 不卡视频一区二区三区 | 99 久久99久久精品免观看 | 公开免费视频 | 视频二区中文字幕 | 九九热re | 午夜精品视频在线观看 | 狠狠色综合久久婷婷 | 综合精品视频 | 青草午夜精品视频在线观看 | 亚综合 | 毛片黄 | 亚洲狠狠狠一区二区三区 | 精品卡1卡2卡三卡免费网站视频 | 美女很黄很黄是免费的·无遮挡网站 | 亚洲卡一卡2卡三卡4卡国色 | 亚洲伊人天堂 | 色综合色狠狠天天综合色hd | 国产精品女丝袜白丝袜 | 天天操天天操天天操天天操 | 在线看片成人 | 好爽毛片一区二区三区四 | 人人人人草 | 国产精品久久久久久久久免费观看 | 国产小视频免费观看 | 美女视频网站色软件免费视频 | 四虎国产精品免费入口 | 久久大尺度| 日本xxx69hd| 日本人的色道www免费一区 |