并行编程之CountdownEvent的用法
一:Barrier(屏障同步)
二:spinLock(自旋锁)
信号量
一:CountdownEvent
虽然通过Task.WaitAll()方法也可以达到线程同步的目的。
但是CountdownEvent更牛X之处在于我们可以动态的改变“信号计数”的大小,比如一会儿能够容纳8个线程,一下又4个,一下又10个,CountdownEvent给我们提供了可以动态修改的解决方案。
模拟建房子工序
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} static CountdownEvent cde = null;
private void button1_Click(object sender, EventArgs e)
{
//建房子第一期工人
string[] _bhPerson1 = new string[] { "Yan", "Zhi", "wei", "Do", "Work" };
//建房子第二期工人
string[] _bhPerson2 = new string[] { "Yan2", "Zhi2", "wei2" };
//建房子第三期工人
string[] _bhPerson3 = new string[] { "Yan3", "Zhi3", "wei3" };
using (cde = new CountdownEvent(Environment.ProcessorCount))//开始监管,相当于监工
{
cde.Reset(_bhPerson1.Length);//设置第一期建造需要5个人
foreach (string person in _bhPerson1)
{
Task.Factory.StartNew(() =>
{
BuilderHourseStep1(person);
}); }
cde.Wait();//等待第一期建造完成
Console.WriteLine("-----------------------"); cde.Reset(_bhPerson2.Length);//设置第二期建需要三个人
foreach (string person in _bhPerson2)
{
Task.Factory.StartNew(() =>
{
BuilderHourseStep2(person);
});
}
cde.Wait();//等待第二期建造完成
Console.WriteLine("-----------------------"); cde.Reset(_bhPerson3.Length);//设置第三期建需要三个人
foreach (string person in _bhPerson3)
{
Task.Factory.StartNew(() =>
{
BuilderHourseStep3(person);
});
}
cde.Wait();//等待第三期建造完成
Console.WriteLine("-----------------------");
}
}
/// <summary>
/// 建房子第一道所需要的工序
/// </summary>
/// <param name="person"></param>
static void BuilderHourseStep1(string person)
{
try
{
Console.WriteLine(string.Format("『{0}』BuilderHourseStep1....", person));
}
finally
{
cde.Signal();//建造完成一点后,通知监工
}
}
/// <summary>
/// 建房子第二道所需要的工序
/// </summary>
/// <param name="person"></param>
static void BuilderHourseStep2(string person)
{
try
{
Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person));
}
finally
{
cde.Signal();
}
}
/// <summary>
/// 建房子第三道所需要的工序
/// </summary>
/// <param name="person"></param>
static void BuilderHourseStep3(string person)
{
try
{
Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person));
}
finally
{
cde.Signal();
}
}
}
分步执行任务
static void Main(string[] args)
{
IList<string> taskList =new List<string> {"任务一","任务二", "任务四", "任务五", "任务六" };
int count = taskList.Count;
using (CountdownEvent cde = new CountdownEvent(Environment.ProcessorCount))
{
cde.Reset(count);//设置信号数
foreach (var item in taskList)
{
Task.Factory.StartNew(() =>
{
Console.WriteLine("处理任务:"+item);
cde.Signal();//每次调用 Signal 时,信号计数都会递减 1。
});
}
cde.Wait();// 在主线程上,对 Wait 的调用将会阻塞,直至信号计数为零。
Console.WriteLine("接下来开始做下一件事情");
cde.Reset(count);//重置信号数
foreach (var item in taskList)
{
Task.Factory.StartNew(() =>
{
Console.WriteLine("继续处理任务:" + item);
cde.Signal();//每次调用 Signal 时,信号计数都会递减 1。
});
}
}
Console.ReadKey();
}
二:SemaphoreSlim
三: ManualResetEventSlim
教程
http://blog.gkarch.com/threading/part5.html#the-parallel-class
http://www.cnblogs.com/huangxincheng/archive/2012/04/08/2437701.html
http://www.cnblogs.com/yaopengfei/p/8315212.html
并行编程之CountdownEvent的用法的更多相关文章
- 并行编程之PLINQ
并行编程之PLINQ 并行 LINQ (PLINQ) 是 LINQ 模式的并行实现.PLINQ 的主要用途是通过在多核计算机上以并行方式执行查询委托来加快 LINQ to Objects 查询的执行速 ...
- .Net并行编程之二:并行循环
本篇内容主要包括: 1.能够转化为并行循环的条件 2.并行For循环的用法:Parallel.For 3.并行ForEach的用法Parallel.ForEach 4.并行LINQ(PLINQ)的用法 ...
- Java并发编程之CountDownLatch的用法
一.含义 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.CountDownLatch是一个同步的辅助类,它可以允许一个或多个线程等待, ...
- Pthreads并行编程之spin lock与mutex性能对比分析(转)
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
- Shell编程之Shift的用法
位置参数可以用shift命令左移.比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1.$2.$3丢弃,$0不移动.不带参数的shift命令相当于shift 1. 非常 ...
- Python网络编程之TCP套接字简单用法示例
Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...
- 异步编程之Promise(3):拓展进阶
异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...
- 深入浅出Cocoa多线程编程之 block 与 dispatch quene
深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...
- [Cocoa]深入浅出Cocoa多线程编程之 block 与 dispatch quene
深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...
随机推荐
- 无法加载程序集,因为该程序集包含EdmSchemaAttribute,并按名称加载结束类型。不允许同时按名称和特性进行加载
小小记录下,今天写程序时遇到的一个bug,相信大家用MVC+EF写项目时遇到的概率是挺大的.昨天本人也遇到了,很悲剧,暂时没想到好的办法解决,跟项目经理交流了下,这个问题认为出现在EF的自身设计上,它 ...
- MFC学习 画图设置字体按钮风格
修改按钮样式时, 设置按钮关联哪个按钮类, 按钮类是自己写的, 从CButton继承, 重写DrawItem可修改按钮样式. 代码中包括画线, 点, 圆, 设置这些的样式, 如线粗, 颜色, 字体. ...
- JAVA面试题基础部分(三)
20.接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法? 接口可以继承接口.抽象类可以实现 ...
- 在使用 百度编辑器 Ueditor 时,不能进入 Controller 相应的 Action 的处理方法
如果在前端的页面中使用了 Ueditor 编辑器,那么在提交表单数据时,将不会执行 期望的 Controller 中的 Action ,造成这样的原因是: 在 MVC 4 的框架中,当前端页面需要提交 ...
- 跟我学 NHibernate (一)
NHibernate 是一个强大的 ORM 框架,本博文主要就 NHibernate 的使用方法及语法做一些简单的介绍. 1.NHibernate 语法 新建一个类,命名为: QueryCrit ...
- 在Tomcat下部属项目三种方式:
在Tomcat下部属项目三种方式: 1直接复制: 2. 通过配置虚拟路径的方式 直接修改配置文件 写到tomcat/conf/server.xml 找到<H ...
- gerrit 调试smtp email
- jQuery插件开发方式
一.jQuery扩展 1.$.extend(object) 类似于.Net的扩展方法,用于扩展jQuery.然后就可以用$.的方式调用. $(function(){ $.extend({ fun1: ...
- OSI(Open System Interconnection)网络模型
OSI模型是国际互连网标准化组织(International Standards Organizations ISO)所定义的,为了使网络的各个层次有标准.这个模型一般被称为“ISO OSI(Open ...
- 用verilog模拟DDS产生正弦波信号
前言: DDS:直接数字频率合成,正弦波0-2pi周期内,相位到幅度是一一对应的(这里我们使用放大后的整数幅度). 主要思路: 个人理解,FPGA不擅长直接做数字信号计算,那样太占用片上逻辑资源,所以 ...