.NET并行计算和并发11:并发接口 IProducerConsumerCollection

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Collections.Concurrent;
  5 using System.Linq;
  6 using System.Threading;
  7 using System.Threading.Tasks;
  8
  9
 10 // Sample implementation of IProducerConsumerCollection(T)
 11 // -- in this case, a thread-safe stack.
 12 public class SafeStack<T> : IProducerConsumerCollection<T>
 13 {
 14     // Used for enforcing thread-safety
 15     private object m_lockObject = new object();
 16
 17     // We‘ll use a regular old Stack for our core operations
 18     private Stack<T> m_sequentialStack = null;
 19
 20     //
 21     // Constructors
 22     //
 23     public SafeStack()
 24     {
 25         m_sequentialStack = new Stack<T>();
 26     }
 27
 28     public SafeStack(IEnumerable<T> collection)
 29     {
 30         m_sequentialStack = new Stack<T>(collection);
 31     }
 32
 33     //
 34     // Safe Push/Pop support
 35     //
 36     public void Push(T item)
 37     {
 38         lock (m_lockObject) m_sequentialStack.Push(item);
 39     }
 40
 41     public bool TryPop(out T item)
 42     {
 43         bool rval = true;
 44         lock (m_lockObject)
 45         {
 46             if (m_sequentialStack.Count == 0) { item = default(T); rval = false; }
 47             else item = m_sequentialStack.Pop();
 48         }
 49         return rval;
 50     }
 51
 52     //
 53     // IProducerConsumerCollection(T) support
 54     //
 55     public bool TryTake(out T item)
 56     {
 57         return TryPop(out item);
 58     }
 59
 60     public bool TryAdd(T item)
 61     {
 62         Push(item);
 63         return true; // Push doesn‘t fail
 64     }
 65
 66     public T[] ToArray()
 67     {
 68         T[] rval = null;
 69         lock (m_lockObject) rval = m_sequentialStack.ToArray();
 70         return rval;
 71     }
 72
 73     public void CopyTo(T[] array, int index)
 74     {
 75         lock (m_lockObject) m_sequentialStack.CopyTo(array, index);
 76     }
 77
 78
 79
 80     //
 81     // Support for IEnumerable(T)
 82     //
 83     public IEnumerator<T> GetEnumerator()
 84     {
 85         // The performance here will be unfortunate for large stacks,
 86         // but thread-safety is effectively implemented.
 87         Stack<T> stackCopy = null;
 88         lock (m_lockObject) stackCopy = new Stack<T>(m_sequentialStack);
 89         return stackCopy.GetEnumerator();
 90     }
 91
 92
 93     //
 94     // Support for IEnumerable
 95     //
 96     IEnumerator IEnumerable.GetEnumerator()
 97     {
 98         return ((IEnumerable<T>)this).GetEnumerator();
 99     }
100
101     //
102     // Support for ICollection
103     //
104     public bool IsSynchronized
105     {
106         get { return true; }
107     }
108
109     public object SyncRoot
110     {
111         get { return m_lockObject; }
112     }
113
114     public int Count
115     {
116         get { return m_sequentialStack.Count; }
117     }
118
119     public void CopyTo(Array array, int index)
120     {
121         lock (m_lockObject) ((ICollection)m_sequentialStack).CopyTo(array, index);
122     }
123 }
124
125 public class Program
126 {
127     static void Main()
128     {
129         TestSafeStack();
130
131         // Keep the console window open in debug mode.
132         Console.WriteLine("Press any key to exit.");
133         Console.ReadKey();
134     }
135
136     // Test our implementation of IProducerConsumerCollection(T)
137     // Demonstrates:
138     //      IPCC(T).TryAdd()
139     //      IPCC(T).TryTake()
140     //      IPCC(T).CopyTo()
141     static void TestSafeStack()
142     {
143         SafeStack<int> stack = new SafeStack<int>();
144         IProducerConsumerCollection<int> ipcc = (IProducerConsumerCollection<int>)stack;
145
146         // Test Push()/TryAdd()
147         stack.Push(10); Console.WriteLine("Pushed 10");
148         ipcc.TryAdd(20); Console.WriteLine("IPCC.TryAdded 20");
149         stack.Push(15); Console.WriteLine("Pushed 15");
150
151         int[] testArray = new int[3];
152
153         // Try CopyTo() within boundaries
154         try
155         {
156             ipcc.CopyTo(testArray, 0);
157             Console.WriteLine("CopyTo() within boundaries worked, as expected");
158         }
159         catch (Exception e)
160         {
161             Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message);
162         }
163
164         // Try CopyTo() that overflows
165         try
166         {
167             ipcc.CopyTo(testArray, 1);
168             Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE");
169         }
170         catch (Exception e)
171         {
172             Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message);
173         }
174
175         // Test enumeration
176         Console.Write("Enumeration (should be three items): ");
177         foreach (int item in stack) Console.Write("{0} ", item);
178         Console.WriteLine("");
179
180         // Test TryPop()
181         int popped = 0;
182         if (stack.TryPop(out popped))
183         {
184             Console.WriteLine("Successfully popped {0}", popped);
185         }
186         else Console.WriteLine("FAILED to pop!!");
187
188         // Test Count
189         Console.WriteLine("stack count is {0}, should be 2", stack.Count);
190
191         // Test TryTake()
192         if (ipcc.TryTake(out popped))
193         {
194             Console.WriteLine("Successfully IPCC-TryTaked {0}", popped);
195         }
196         else Console.WriteLine("FAILED to IPCC.TryTake!!");
197     }
198 }
199 
时间: 2025-01-11 08:30:49

.NET并行计算和并发11:并发接口 IProducerConsumerCollection的相关文章

C++ 11 并发: 正确 的使用条件变量-condition_variable

1. 标准实例 http://en.cppreference.com/w/cpp/thread/condition_variable 在cppreference提供的对 cv的例子,condition_variable和mutex都是全局变量.但是我们的程序不可能到处使用全局变量.如果把condition_variable和mutex的定义放到main函数中进去,作为局部变量,并且循环几次,会发现第一次同步OK,后面的就没有那么好的运气了. 因此对于局部变量中如何正确的使用condition_v

C++11 并发指南系列(转)

本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C++11 并发指南二(std::thread 详解)(本章计划 1-2 篇,已完成 1 篇) C++11 并发指南三(std::mutex 详解)(本章计划 1-2 篇,已完成 2 篇) C++11 并发指南三(std::mutex 详解) C++11 并发指南三(Lock 详解) C++11 并发

【转】C++11 并发指南五(std::condition_variable 详解)

http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mutex,std::future 等相关内容,相信读者对 C++11 中的多线程编程有了一个最基本的认识,本文将介绍 C++11 标准中 <condition_variable> 头文件里面的类和相关函数. &l

C++11并发编程入门

也许有人会觉得多线程和并发难用,复杂,还会让代码出现各种各样的问题,不过,其实它是一个强有力的工具,能让程序充分利用硬件资源,让程序运行得更快. 何谓并发: 两个或更多独立得活动同时发生.计算机中就是单个系统同时执行多个独立的任务,通过这个任务做一会儿,再切换到别的任务再做一会儿的方式,让任务看起来是并行执行的.切换就是做上下文切换,会有时间开销,操作系统为当前运行的任务保存CPU的状态和指针,计算出要切换到哪一个任务,并为即将切换到的任务重新加载处理器状态. 并发的方式: 多进程并发 多线程并

C++11 并发指南三(std::mutex 详解)

C++11 并发指南三(std::mutex 详解) 上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mutex> 头文件中,所以如果你需要使用 std::mutex,就必须包含 <mutex> 头文件. <mutex> 头文件介绍 Mu

Java多线程与高并发:高并发解决思路

Java多线程与高并发:高并发解决思路 小玲子之凌空蹈虚关注 122018.11.21 09:55:30字数 1,553阅读 4,228 來源:http://www.wangtianyi.top/blog/2018/05/11/javaduo-xian-cheng-yu-gao-bing-fa-liu-gao-bing-fa-jie-jue-si-lu/ 缓存并发 image.png 当大量请求访问同一个没有被缓存的数据的时候,会发送大量请求给数据库,导致数据库压力过大,还会导致一致性问题,所以

Linux-Shell-使用mkfifo实现多任务并发及并发数控制

默认的情况下,Shell脚本中的命令是串行执行的,必须等到前一条命令执行完后才执行接下来的命令,但是如果我有一大批的的命令需要执行,而且互相又没有影响的情况下(有影响的话就比较复杂了),那么就要使用命令的并发执行了. 如下: #!/bin/bash IPLIST=/home/meta/ipinfo/iplist for i in $(cat ${IPLIST} |grep -viE "^#|备机|ts"|awk '{print $1}') do ssh $i "cd ~/up

使用 C++11 并发编程入门

一.认识并发和并行 先将两个概念, 并发与并行 并发:同一时间段内可以交替处理多个操作: 图中整个安检系统是一个并发设计的结构.两个安检队列队首的人竞争这一个安检窗口,两个队列可能约定交替着进行安检,也可能是大家同时竞争安检窗口(通信).后一种方式可能引起冲突:因为无法同时进行两个安检操作.在逻辑上看来,这个安检窗口是同时处理这两个队列 并行:同一时刻内同时处理多个操作: 图中整个安检系统是一个并行的系统.在这里,每个队列都有自己的安检窗口,两个队列中间没有竞争关系,队列中的某个排队者只需等待队

C++11 并发编程基础(一):并发、并行与C++多线程

正文 C++11标准在标准库中为多线程提供了组件,这意味着使用C++编写与平台无关的多线程程序成为可能,而C++程序的可移植性也得到了有力的保证.另外,并发编程可提高应用的性能,这对对性能锱铢必较的C++程序员来说是值得关注的. 回到顶部 1. 何为并发 并发指的是两个或多个独立的活动在同一时段内发生.生活中并发的例子并不少,例如在跑步的时候你可能同时在听音乐:在看电脑显示器的同时你的手指在敲击键盘.这时我们称我们大脑并发地处理这些事件,只不过我们大脑的处理是有次重点的:有时候你会更关注你呼吸的