c# 并行运算
c# 并行运算
1. Parallel.INVOKE() 看实例:
private static Stopwatch watch = new Stopwatch();
private static void Run1()
{
Thread.Sleep();
Console.WriteLine("Task 1 takes 2 sec");
}
private static void Run2()
{
Thread.Sleep();
Console.WriteLine("Task 2 takes 3 sec");
}
static void Main(string[] args)
{
watch.Start();
Parallel.Invoke(Run1,Run2);
watch.Stop();
Console.WriteLine("Parallel run "+watch.ElapsedMilliseconds +" ms");
watch.Restart();
Run1();
Run2();
watch.Stop();
Console.WriteLine("Normal run "+watch.ElapsedMilliseconds+" ms");
Console.ReadLine();
看结果:

2.Parallel.For
看实例:
watch.Start();
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
int sum = ;
sum++;
}
}
watch.Stop();
Console.WriteLine("Normal run " + watch.ElapsedMilliseconds + "ms"); watch.Restart();
watch.Start();
Parallel.For(, , item =>
{
for (int j = ; j < ; j++)
{
int sum = ;
sum += item;
} }); watch.Stop();
Console.WriteLine("ParalleFor run " + watch.ElapsedMilliseconds + "ms"); Console.ReadLine();
看结果:

是不是Parallel.For在任何时候都比for要快呢?答案当然是“不是”,要不然微软还留着for干嘛?
看实例:
var obj = new object();
long num = ;
ConcurrentBag<long> bag = new ConcurrentBag<long>();
watch.Start();
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
// int sum = 0;
// sum++;
num++;
}
} watch.Stop();
Console.WriteLine("Normal run "+watch.ElapsedMilliseconds+ "Ms"); watch.Restart(); Parallel.For(, , item =>
{
for (int j = ; j < ; j++)
{
//int sum = 0;
//sum += item;
lock (obj)
{
num++; //全局变量,就要考虑到线程安全了
//这主要是由于并行同时访问全局变量,会出现资源争夺,大多数时间消耗在了资源等待上面。
}
} }); watch.Stop();
Console.WriteLine("ParalleFor run " + watch.ElapsedMilliseconds + "ms"); Console.ReadLine();
结果:(结果不是稳定的,你懂得~)

再看代码:
Parallel.For(, , i =>
{
Console.Write( i +"\t");
}); Console.ReadLine();
再看结果:

傻孩子,这样你懂了吧~
3.Parallel.Foreach
//Environment.ProcessorCount能够获取到当前的硬件线程数,所以这里也就开了2个区。
Console.WriteLine(Environment.ProcessorCount);
Console.ReadLine();
//继续我的并发编程; //可以将数据进行分区,每一个小区内实现串行计算;分区采用Create实现; for (int j = ; j < ; j++)
{
Console.WriteLine("\n第{0}次比较", j);
ConcurrentBag<int> bag = new ConcurrentBag<int>();
watch.Start(); for (int i = ; i < ; i++)
{
bag.Add(i);
} Console.WriteLine("串行计算:集合有{0},总共耗时:{1}",bag.Count,watch.ElapsedMilliseconds); GC.Collect();
bag = new ConcurrentBag<int>();
watch.Restart();
Parallel.ForEach(Partitioner.Create(, ), i =>
{
for (int m = i.Item1; m < i.Item2; m++)
{
bag.Add(m);
}
});
Console.WriteLine("并行计算:集合有:{0},总共耗时:{1}", bag.Count, watch.ElapsedMilliseconds); GC.Collect();
watch.Stop();
} Console.ReadLine();
结果:

4.parallel 中途退出循环
Break: 当然这个是通知并行计算尽快的退出循环,比如并行计算正在迭代100,那么break后程序还会迭代所有小于100的。
Stop:这个就不一样了,比如正在迭代100突然遇到stop,那它啥也不管了,直接退出。
ConcurrentBag<long> bag = new ConcurrentBag<long>();
watch.Start(); Parallel.For(,, (i, state) =>
{
if (bag.Count == )
{
state.Break();
//当数量达到300个时,会立刻停止;可以看到结果"Bag count is 300",如果用break,可能结果是300多个或者300个,大家可以测试一下。
return;
}
bag.Add(i); });
watch.Stop();
Console.WriteLine("Bag count is "+bag.Count+" times is "+watch.ElapsedMilliseconds);
异常处理
由于Task的Start方法是异步启动的,所以我们需要额外的技术来完成异常处理
try
{
var parallelExceptions = new ConcurrentQueue<Exception>();
Parallel.For(, , (i) =>
{
try
{
throw new InvalidOperationException("并行任务中出现的异常");
}
catch (Exception e)
{
parallelExceptions.Enqueue(e);
}
if (parallelExceptions.Count > )
throw new AggregateException(parallelExceptions);
});
}
catch (AggregateException err)
{
foreach (Exception item in err.InnerExceptions)
{
Console.WriteLine("异常类型:{0}{1}来自:
{}{}异常内容:{}", item.InnerException.GetType(),
Environment.NewLine, item.InnerException.Source,
Environment.NewLine, item.InnerException.Message);
}
}
Console.WriteLine("主线程马上结束");
Console.ReadKey();
static void Main(string[] args)
{
try
{
Parallel.Invoke(Run1, Run2);
//这个捕获
//在不同的模式下,会有不同结果地呀;
//debug 模式下,会停止的
//realse 模式下就可以获取异常;
}
catch (AggregateException ex)
{
foreach (var single in ex.InnerExceptions)
{
Console.WriteLine(single.Message);
}
} Console.Read();
} static void Run1()
{
Thread.Sleep();
throw new Exception("我是任务1抛出的异常");
} static void Run2()
{
Thread.Sleep(); throw new Exception("我是任务2抛出的异常");
}
实例二
try
{
go1(); //这样的异常只能捕获其中一个地呀; go2();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
watch.Stop();
Console.WriteLine("Normal run :" + watch.ElapsedMilliseconds);
//尼玛的,这样的异常,居然捕获不到的地呀
默认的情况下,底层机制会尽可能多的使用硬件线程,然而我们使用手动指定的好处是我们可以在2,4,8个硬件线程的情况下来进行测量加速比。
class Program
{
static void Main(string[] args)
{
var bag = new ConcurrentBag<int>(); ParallelOptions options = new ParallelOptions(); //指定使用的硬件线程数为1
options.MaxDegreeOfParallelism = ; Parallel.For(, , options, i =>
{
bag.Add(i);
}); Console.WriteLine("并行计算:集合有:{0}", bag.Count); }
}
c# 并行运算的更多相关文章
- 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...
- Scalaz(59)- scalaz-stream: fs2-程序并行运算,fs2 running effects in parallel
scalaz-stream-fs2是一种函数式的数据流编程工具.fs2的类型款式是:Stream[F[_],O],F[_]代表一种运算模式,O代表Stream数据元素的类型.实际上F就是一种延迟运算机 ...
- Scalaz(52)- scalaz-stream: 并行运算-parallel processing concurrently by merging
如果scalaz-stream真的是一个实用的数据流编程工具库的话,那它应该能处理同时从多个数据源获取数据以及把数据同时送到多个终点(Sink),最重要的是它应该可以实现高度灵活的多线程运算.但是:我 ...
- SQL Server调优系列基础篇(并行运算总结)
前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...
- SQL Server调优系列基础篇(并行运算总结篇二)
前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...
- 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
[源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...
- ahjesus C# 4.0 Parallel 并行运算
Parallel.For - for 循环的并行运算 Parallel.ForEach - foreach 循环的并行运算 Parallel.Invoke - 并行调用多个任务 Task - 任务,基 ...
- Parallel并行运算实例
并行运算Parallel,是.net 4.0版本里添加的新处理方式,主要充分利用CPU.任务并发的模式来达到提高运算能力.简单理解为每个CPU都在处理任务,而不会让它们空闲下来. 直接看实例: nam ...
- Python串行运算、并行运算、多线程、多进程对比实验
转自:http://www.redicecn.com/html/Python/20111223/355.html Python发挥不了多核处理器的性能(据说是受限于GIL,被锁住只能用一个CPU核心, ...
随机推荐
- [shell] if else以及大于、小于、等于逻辑表达式 [转]
本文也即<Learning the bash Shell>3rd Edition的第五章Flow Control之读书笔记,但我们将不限于此.flow control是任何编程语言中很常用 ...
- jquery easyui datagrid 分页详解
由于项目原因,用了jquery easyui 感觉界面不错,皮肤样式少点,可是官网最近打不开了,资料比较少,给的demo没有想要的效果,今天在用datagrid 做分页显示的时候,折腾了半天,网上的资 ...
- 让IE下支持Html5的placeholder属性
HTML5对Web Form做了许多增强,比如input新增的type类型.Form Validation等. Placeholder 是HTML5新增的另一个属性,当input或者textarea设 ...
- QCheckBox 的按钮响应
Qt中QCheckBox的按键响应如下,其中checkbox为对象名: void YourClass::on_checkbox_toggled(bool state) { // Do somethin ...
- mysql多种方法修改密码----5.6的坑
创建用户并授权和改密码: grant all privileges on *.* to root@'%' identified by '123456' with grant option; * ...
- ajax利用json进行服务器与客户端的通信
1.JQuery中$.ajax()方法参数详解 http://blog.sina.com.cn/s/blog_4f925fc30100la36.html 2.服务器端获取String que=requ ...
- Java集合之Collection接口
java的集合分为三大接口,分别是Collection,Map,Iterator,集合接口和类在java.util包中,此次主要介绍三大接口之一的Collection接口. 一些Collection允 ...
- twitter storm源码走读之1 -- nimbus启动场景分析
欢迎转载,转载时请注明作者徽沪一郎及出处,谢谢. 本文详细介绍了twitter storm中的nimbus节点的启动场景,分析nimbus是如何一步步实现定义于storm.thrift中的servic ...
- swift 子类继承父类
// 子类的指定构造方法必须调用父类构造方法,并确保调用发生在子类存储属性初始化之后.而且指定构造方法不能调用同一个类中的其他指定构造方法: // 便利构造方法必须调用同一个类中的其他指定构造方法(可 ...
- Oracle 删除重复行
DELETE FROM your_table WHERE rowid not in (SELECT MIN(rowid) FROM your_table GROUP BY column1, colum ...