国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

ParallelProgramming-實現并行操作的流水線(生產者、消費者)

2019-11-14 13:46:45
字體:
來源:轉載
供稿:網友

本文介紹如何使用C#實現并行執行的流水線(生產者消費者):

  1. 流水線示意圖
  2. 實現并行流水線

 

一、流水線示意圖

上圖演示了流水線,action1接收input,然后產生結果保存在buffer1中,action2讀取buffer1中由action1產生的數據,以此類推指導action4完成產生Output。

以上也是典型的生產者消費者模式

上面的模式如果使用普通常規的串行執行是很簡單的,按部就班按照流程圖一步一步執行即可。如果為了提高效率,想使用并行執行,也就是說生產者和消費者同時并行執行,該怎么辦么?

二、實現并行流水線

2.1 代碼

class PiplelineDemo    {        PRivate int seed;        public PiplelineDemo()        {            seed = 10;        }        public void Action1(BlockingCollection<string> output)        {            try            {                for (var i = 0; i < seed; i++)                {                    output.Add(i.ToString());//initialize data to buffer1                }            }            finally            {                output.CompleteAdding();            }        }        public void Action2(BlockingCollection<string> input, BlockingCollection<string> output)        {            try            {                foreach (var item in input.GetConsumingEnumerable())                {                    var itemToInt = int.Parse(item);                    output.Add((itemToInt * itemToInt).ToString());// add new data to buffer2                }            }            finally            {                output.CompleteAdding();            }        }        public void Action3(BlockingCollection<string> input, BlockingCollection<string> output)        {            try            {                foreach (var item in input.GetConsumingEnumerable())                {                    output.Add(item);//set data into buffer3                }            }            finally            {                output.CompleteAdding();            }        }        public void Pipeline()        {            var buffer1 = new BlockingCollection<string>(seed);            var buffer2 = new BlockingCollection<string>(seed);            var buffer3 = new BlockingCollection<string>(seed);            var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);            var stage1 = taskFactory.StartNew(() => Action1(buffer1));            var stage2 = taskFactory.StartNew(() => Action2(buffer1, buffer2));            var stage3 = taskFactory.StartNew(() => Action3(buffer2, buffer3));            Task.WaitAll(stage1, stage2, stage3);            foreach(var item in buffer3.GetConsumingEnumerable())//print data in buffer3            {                Console.WriteLine(item);            }        }    }    class Program    {        static void Main(string[] args)        {            new PiplelineDemo().Pipeline();            Console.Read();        }    }

2.2 運行結果

預期打印出了0-9自我相乘的結果。

2.3 代碼解釋

代碼本身的邏輯和本文開始的流程圖是一一對應的。

BlockingCollection<T>是.Net里面的一個線程安全集合。實現了IProducerConsumerCollection<T>.

  1. Add方法:將元素加入集合
  2. CompleteAdding方法:告訴消費者,在當調用該方法之前的元素處理完之后就不要再等待處理了,可以結束處理了。這個非常重要,一定要執行,所以放在finally中(就算exception也要執行)
  3. GetConsumingEnumberable,給消費者返回一個可以便利的集合

GetConsumingEnumberable是一個非常強大的東東,專門寫一片文章介紹介紹。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安西县| 大竹县| 巴中市| 全椒县| 长丰县| 巴东县| 凭祥市| 诸暨市| 龙里县| 海伦市| 平罗县| 子长县| 洪泽县| 迁安市| 余江县| 内乡县| 开封县| 古田县| 萝北县| 南城县| 潼关县| 林芝县| 内黄县| 台东市| 婺源县| 寿阳县| 新乡市| 密山市| 江北区| 文安县| 奉贤区| 湛江市| 呼图壁县| 城固县| 博野县| 垦利县| 北京市| 遵义市| 竹北市| 道孚县| 精河县|