最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#并行編程之信號量

 更新時間:2022年05月09日 14:47:52   作者:springsnow  
這篇文章介紹了C#并行編程之信號量,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一:CountdownEvent

這種采用信號狀態(tài)的同步基元非常適合在動態(tài)的fork,join的場景,它采用“信號計數(shù)”的方式,就比如這樣,一個麻將桌只能容納4個人打麻將,如果后來的人也想搓一把碰碰運氣,那么他必須等待直到麻將桌上的人走掉一位。好,這就是簡單的信號計數(shù)機制,從技術角度上來說它是定義了最多能夠進入關鍵代碼的線程數(shù)。

但是CountdownEvent更牛X之處在于我們可以動態(tài)的改變“信號計數(shù)”的大小,比如一會兒能夠容納8個線程,一下又4個,一下又10個,這樣做有什么好處呢?還是承接上一篇文章所說的,比如一個任務需要加載1w條數(shù)據(jù),那么可能出現(xiàn)這種情況。

加載User表:根據(jù)user表的數(shù)據(jù)量,我們需要開5個task。

加載Product表:產(chǎn)品表數(shù)據(jù)相對比較多,計算之后需要開8個task。

加載order表:由于我的網(wǎng)站訂單豐富,計算之后需要開12個task。

先前的文章也說了,我們需要協(xié)調(diào)task在多階段加載數(shù)據(jù)的同步問題,那么如何應對這里的5,8,12,幸好,CountdownEvent給我們提供了可以動態(tài)修改的解決方案。

我們看到有兩個主要方法:Wait和Signal。每調(diào)用一次Signal相當于麻將桌上走了一個人,直到所有人都搓過麻將wait才給放行,這里同樣要注意也就是“超時“問題的存在性,尤其是在并行計算中,輕量級別給我們提供了”取消標記“的機制,這是在重量級別中不存在的,比如下面的重載public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken),具體使用可以看前一篇文章的介紹。

//默認的容納大小為“硬件線程“數(shù)
static CountdownEvent cde = new CountdownEvent(Environment.ProcessorCount);

static void Main(string[] args)
{
    //加載User表需要5個任務
    var userTaskCount = 5;

    //重置信號
    cde.Reset(userTaskCount);

    for (int i = 0; i < userTaskCount; i++)
    {
        Task.Factory.StartNew((obj) =>
        {
            LoadUser(obj);
        }, i);
    }

    //等待所有任務執(zhí)行完畢
    cde.Wait();

    Console.WriteLine("\nUser表數(shù)據(jù)全部加載完畢!\n");

    //加載product需要8個任務
    var productTaskCount = 8;

    //重置信號
    cde.Reset(productTaskCount);

    for (int i = 0; i < productTaskCount; i++)
    {
        Task.Factory.StartNew((obj) =>
        {
            LoadProduct(obj);
        }, i);
    }

    cde.Wait();

    Console.WriteLine("\nProduct表數(shù)據(jù)全部加載完畢!\n");

    //加載order需要12個任務
    var orderTaskCount = 12;

    //重置信號
    cde.Reset(orderTaskCount);

    for (int i = 0; i < orderTaskCount; i++)
    {
        Task.Factory.StartNew((obj) =>
        {
            LoadOrder(obj);
        }, i);
    }

    cde.Wait();

    Console.WriteLine("\nOrder表數(shù)據(jù)全部加載完畢!\n");

    Console.WriteLine("\n(*^__^*) 嘻嘻,恭喜你,數(shù)據(jù)全部加載完畢\n");

    Console.Read();
}

static void LoadUser(object obj)
{
    try
    {
        Console.WriteLine("當前任務:{0}正在加載User部分數(shù)據(jù)!", obj);
    }
    finally
    {
        cde.Signal();
    }
}

static void LoadProduct(object obj)
{
    try
    {
        Console.WriteLine("當前任務:{0}正在加載Product部分數(shù)據(jù)!", obj);
    }
    finally
    {
        cde.Signal();
    }
}

static void LoadOrder(object obj)
{
    try
    {
        Console.WriteLine("當前任務:{0}正在加載Order部分數(shù)據(jù)!", obj);
    }
    finally
    {
        cde.Signal();
    }
}

二:SemaphoreSlim

在.net 4.0之前,framework中有一個重量級的Semaphore,人家可以跨進程同步,咋輕量級不行,msdn對它的解釋為:限制可同時訪問某一資源或資源池的線程數(shù)。關于它的重量級demo,我的上一個系列有演示,你也可以理解為CountdownEvent是 SemaphoreSlim的功能加強版,好了,舉一個輕量級使用的例子。

static SemaphoreSlim slim = new SemaphoreSlim(Environment.ProcessorCount, 12);

static void Main(string[] args)
{
    for (int i = 0; i < 12; i++)
    {
        Task.Factory.StartNew((obj) =>
        {
            Run(obj);
        }, i);
    }

    Console.Read();
}

static void Run(object obj)
{
    slim.Wait();

    Console.WriteLine("當前時間:{0}任務 {1}已經(jīng)進入。", DateTime.Now, obj);

    //這里busy3s中
    Thread.Sleep(3000);

    slim.Release();
}

同樣,防止死鎖的情況,我們需要知道”超時和取消標記“的解決方案,像SemaphoreSlim這種定死的”線程請求范圍“,其實是降低了擴展性,所以說,試水有風險,使用需謹慎,在覺得有必要的時候使用它。

三: ManualResetEventSlim

相信它的重量級別大家都知道是ManualReset,而這個輕量級別采用的是"自旋等待“+”內(nèi)核等待“,也就是說先采用”自旋等待的方式“等待,直到另一個任務調(diào)用set方法來釋放它。如果遲遲等不到釋放,那么任務就會進入基于內(nèi)核的等待,所以說如果我們知道等待的時間比較短,采用輕量級的版本會具有更好的性能,原理大概就這樣,下面舉個小例子。

//2047:自旋的次數(shù)
 static ManualResetEventSlim mrs = new ManualResetEventSlim(false, 2047);

 static void Main(string[] args)
 {

     for (int i = 0; i < 12; i++)
     {
         Task.Factory.StartNew((obj) =>
         {
             Run(obj);
         }, i);
     }

     Console.WriteLine("當前時間:{0}我是主線程{1},你們這些任務都等2s執(zhí)行吧:\n",
     DateTime.Now,
     Thread.CurrentThread.ManagedThreadId);
     Thread.Sleep(2000);

     mrs.Set();
 }

 static void Run(object obj)
 {
     mrs.Wait();

     Console.WriteLine("當前時間:{0}任務 {1}已經(jīng)進入。", DateTime.Now, obj);
 }

到此這篇關于C#并行編程之信號量的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • C# Csv實現(xiàn)基本的讀寫和轉(zhuǎn)換DataTable

    C# Csv實現(xiàn)基本的讀寫和轉(zhuǎn)換DataTable

    本文主要介紹了C# Csv實現(xiàn)基本的讀寫和轉(zhuǎn)換DataTable,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • 調(diào)整C#中數(shù)組大小的方法

    調(diào)整C#中數(shù)組大小的方法

    數(shù)組存儲多個相同類型的一種非常常用的數(shù)據(jù)結(jié)構(gòu),它長度是固定,也就是數(shù)組一旦創(chuàng)建大小就固定了,C# 數(shù)組不支持動態(tài)長度,那在C#中是否有方法可以調(diào)整數(shù)組大小呢?本文將通過示例介紹一種調(diào)整一維數(shù)組大小的方法,需要的朋友可以參考下
    2024-06-06
  • 深入分析C#連接Oracle數(shù)據(jù)庫的連接字符串詳解

    深入分析C#連接Oracle數(shù)據(jù)庫的連接字符串詳解

    本篇文章是對C#連接Oracle數(shù)據(jù)庫的連接字符串進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 泛型編程去掉字段重復數(shù)據(jù)的方法

    泛型編程去掉字段重復數(shù)據(jù)的方法

    這篇文章主要介紹了泛型去掉字段重復數(shù)據(jù)的方法,大家參考使用吧
    2014-01-01
  • C#中的IDisposable模式用法詳解

    C#中的IDisposable模式用法詳解

    這篇文章主要介紹了C#中的IDisposable模式用法,講述了垃圾資源回收機制的實現(xiàn),并對比分析了Dispose()方法、~DisposableClass()析構(gòu)函數(shù)、虛方法Dispose(bool disposing)的原理,需要的朋友可以參考下
    2014-09-09
  • 解析C#自定義控件的制作與使用實例的詳解

    解析C#自定義控件的制作與使用實例的詳解

    本篇文章是對C#中自定義控件的制作與使用實例進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C#中的預處理器指令詳解

    C#中的預處理器指令詳解

    這篇文章主要介紹了C#中的預處理器指令詳解,本文講解了#define 和 #undef、#if、#elif、#else和#endif、#warning和#error、#region和#endregion、#line、#pragma等預處理器指令,需要的朋友可以參考下
    2015-01-01
  • C# 禁止應用程序多次啟動的實例

    C# 禁止應用程序多次啟動的實例

    經(jīng)常我們會有這樣的需求,只讓應用程序運行一個實體,下面是實現(xiàn)的方法,有需要的朋友可以參考一下
    2013-09-09
  • C#與SQL連接:GridView控件對數(shù)據(jù)庫的操作

    C#與SQL連接:GridView控件對數(shù)據(jù)庫的操作

    GridView控件操作方面的知識,需要的朋友可以參考一下
    2013-02-02
  • C# WinForm導出Excel方法介紹

    C# WinForm導出Excel方法介紹

    在.NET應用中,導出Excel是很常見的需求,導出Excel報表大致有以下三種方式:Office PIA,文件流和NPOI開源庫,本文只介紹前兩種方式
    2013-12-12

最新評論

乌鲁木齐县| 大宁县| 比如县| 壤塘县| 吉安县| 怀柔区| 雅江县| 石家庄市| 岐山县| 正阳县| 凉城县| 桃源县| 黑龙江省| 石家庄市| 寿宁县| 桂林市| 城步| 厦门市| 平武县| 乳源| 阜康市| 清徐县| 镇宁| 友谊县| 莱西市| 辉县市| 江门市| 绵阳市| 乐陵市| 十堰市| 鞍山市| 徐州市| 同江市| 哈密市| 正宁县| 武威市| 囊谦县| 梅州市| 新乡县| 甘孜| 长葛市|