PDC 2010 Hejlsberg的演讲中我们看到了VB.NET、C#新的简化异步编程的方式(可以下载新的Async CTP体验)。之前的TPL(Task Parallel Library)简化了并行编程。工业语言的飞速发展大大改进、简化了开发人员的编程方式。不仅是微软平台的托管语言,非托管语言也始终保持着一定程度的进化,我想通过两三篇文章来讲述Visual C++ 2010并行编程相关的内容。在介绍Visual C++ 2010的ppl之前,先简单介绍两个比较重要的新语法特性:

1、auto关键字

Visual C++ 2010中的auto关键字不再是以前简单的自动变量的概念,它被用于简化变量原型编译时的自动化推导。

1 vector numVec;
2
3 for (vector::const_iterator iter = numVec.begin(); iter != numVec.end(); ++iter) {
4
5 }

vector的遍历器写法稍微有些长了,代码过于烦琐。现在使用auto关键字编写:

1 vector numVec;
2
3 for (auto iter = numVec.begin(); iter != numVec.end(); ++iter) {
4
5 }

auto关键字的用法和C# 3.0新增的var关键字相同,用于简化那些编译时可以确定类型的声明。

1 Int32[] numArray = { 1, 2, 3, 4, 5 };
2 IOrderedEnumerable iter = numArray.Where(p => p > 0).OrderBy(p => p);
3 var iter2 = iter;

2、Lambda表达式

微软平台的托管语言都支持匿名函数,Lambda是为实现匿名函数提供了函数式的语法。

1 Int32[] numArray = { 1, 2, 3, 4, 5 };
2 var iter = numArray.Where(p => p > 0).Max();

旧有的Visual C++对于编写STL sort函数自定义排序需要这么编写:

1 bool less2(const int& lhs, const int& rhs) {
2     return lhs < rhs;
3 }
4
5 vector numVec;
6
7 sort(numVec.begin(), numVec.end(), less2);
8 sort(numVec.begin(), numVec.end(), less<int>());

Visual C++ 2010:

1 vector numVec;
2
3 sort(numVec.begin(), numVec.end(), [&](int& lhs, int& rhs) { return lhs < rhs; });

对于一些不超过4、5行以上的代码,我个人更愿意使用匿名函数。Visual C++ 2010的ppl的定义被包含在ppl.h中。下面先看一段简单的代码:

 1 #include <iostream>
 2
 3 using namespace std;
 4
 5 int sum = 0;
 6
 7 for (int i = 1; i < 101; ++i)
 8     sum += i;
 9
10 wcout << “Result=” << sum << endl;

这组操作如果基于ppl该如何编写:

 1 #include <iostream>
 2 #include <ppl.h>
 3
 4 using namespace std;
 5 using namespace Concurrency;
 6
 7 int sum = 0;
 8
 9 parallel_for(1, 101, 1, [&](int n) {
10     sum += n;
11 });
12
13 wcout << “Result=” << sum << endl;

ppl提供了parallel_for,它的处理方式和for循环语句一样,下面是parallel_for在ppl.h中的定义:

1 template
2 void parallel_for(_Index_type _First, _Index_type _Last, _Index_type _Step, const _Function& _Func)

_First为起始索引、_Last为结束索引、_Step为步长、_Func为被调用函数指针。我以前的文章提到过Visual C++ 2008开始就提供了for each的支持,对于遍历vector之类的STL容器可以用for each实现(Visual C++的for each在for和each之间是有空格的,和Visual C#不同):

1 vector numVec;
2
3 numVec.push_back(1);
4
5 for each (int i in numVec) {
6     wcout << i << endl;
7 }

同样的ppl也提供了for each版本的并行函数parallel_for_each:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <ppl.h>
 4
 5 using namespace std;
 6 using namespace Concurrency;
 7
 8 int sum = 0;
 9 const int NUMBER_ARRAY_SIZE = 10;
10 int numArray[NUMBER_ARRAY_SIZE];
11
12 generate(numArray, numArray + NUMBER_ARRAY_SIZE, rand);
13
14 parallel_for_each(numArray, numArray + NUMBER_ARRAY_SIZE, [&](int n) {
15     sum += n;
16 });
17
18 wcout << “Result=” << sum << endl;

上面提到的parallel_for和parallel_for_each都是基于容器的遍历,ppl提供了parallel_invoke用于并行执行多个函数体。

 1 #include “stdafx.h”
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <ppl.h>
 5
 6 using namespace std;
 7 using namespace Concurrency;
 8
 9 void Func1() {
10     int sum = 0;
11     const int NUMBER_ARRAY_SIZE = 10;
12     int numArray[NUMBER_ARRAY_SIZE];
13
14     generate(numArray, numArray + NUMBER_ARRAY_SIZE, rand);
15
16     for each (int n in numArray) {
17         sum += n;
18     }
19
20     wcout << “Result=” << sum << endl;
21 }
22
23 parallel_invoke(&Func1, &Func1);

parallel_invoke最多支持10个function的函数重载。超过10以上的function完全可以用parallel_for和parallel_for_each来实现调用。

ppl提供了一些容器类型和对象用于线程安全的操作。先简单介绍两个容器类型concurrent_vector和concurrent_queue。这两个容器的使用方式和普通的STL的vector和queue相同,但有一个非常重要的区别在于它们的存储空间不是连续的,比如原来你操作vector时可以通过指针加减操作进行数据访问:

1 vector<int> vecArray;
2
3 int val = *(&vecArray[0] + 5);

但是对于concurrent_vector、concurrent_queue使用这种访问方式它的结果是未定义的,可能访问成功,可能是已经分配使用的内存空间或者访问违例。

1、concurrent_vector(使用方式和STL的vector相同)

 1 #include <iostream>
 2 #include <ppl.h>
 3 #include <concurrent_vector.h>
 4
 5 concurrent_vector<int> vecArray;
 6
 7 parallel_invoke(
 8 [&vecArray] {
 9     for (int i = 0; i < 50; ++i)
10         vecArray.push_back(rand());
11 },
12 [&vecArray] {
13     for (int i = 0; i < 100; ++i)
14         vecArray.push_back(rand());
15 });
16
17 for each (int n in vecArray)
18     wcout << n << endl;

2、concurrent_queue(STL的queue在访问元素时调用pop,而concurrent_queue则是try_pop)

 1 #include <iostream>
 2 #include <ppl.h>
 3 #include <concurrent_queue.h>
 4
 5 concurrent_queue<int> queueArray;
 6
 7 parallel_invoke(
 8 [&queueArray] {
 9     for (int i = 0; i < 50; ++i)
10         queueArray.push(rand());
11 },
12 [&queueArray] {
13     for (int i = 0; i < 100; ++i)
14         queueArray.push(rand());
15 });
16
17 int val = 0;
18
19 while (!queueArray.empty() && queueArray.try_pop(val))
20     wcout << val << endl;

ppl提供了一种可以合并操作的类型用于将不同线程间的本地存储值进行一定的操作,以往我们编写一个多线程或者并行操作计算总和的时候需要通过各种手段来确保操作值的更新,看一个最简单的例子:

1 volatile long sum2 = 0;
2
3 parallel_for(1, 101, [&sum2](int n) {
4     InterlockedExchangeAdd(&sum2, n);
5 });
6
7 wcout << sum2 << endl;

再来看使用ppl新增的combinable类型完成同样的操作:

 1 #include <iostream>
 2 #include <ppl.h>
 3
 4 combinable sum3;
 5
 6 parallel_for(1, 101, [&sum3](int n) {
 7     int& local = sum3.local();
 8
 9     local += n;
10 });
11
12 wcout << sum3.combine(plus()) << endl;

combinable的combine是一个模板函数用来定义函数指针,所以完全可以通过简单的lambda表达式定义自己的操作。默认提供了诸如:plus、multiplies、divides、minus操作。上面的例子最后一步的combine也可以这样写:

wcout << sum3.combine([&](int n1, int n2) { return n1 + n2; }) << endl;

转载于:https://www.cnblogs.com/junchu25/archive/2012/08/11/2633505.html

Concurrency Runtime in Visual C++ 2010相关推荐

  1. 安装Visual studio 2010 Tools For office Runtime时找不到vc_red.msi报错

    安装MySQL时需要安装Visual studio 2010 Tools For office Runtime,但是安装时会提示缺少vc_red.msi文件如下图所示 此时安装MSVBCRT_AIO_ ...

  2. CSDN著名技术专家Visual C++2010开发体验心得——从Visual C++6 0到Visual C++201

    IT业是一个创造奇迹的行业,IT业也是一个年轻的行业,IT业更是一个不断更新的行业.在2009年,微软已经连续推出Visual Studio2010 beta1 与 Visual Studio2010 ...

  3. CSDN著名技术专家Visual C++2010开发体验心得——从Visual C++6.0到Visual C++2010见证VC++辉煌时刻

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! IT业是 ...

  4. ASP.NET 4 和 Visual Studio 2010 Web 开发概述

    声明:本文是ASP.NET 白皮书 ASP.NET 4 and Visual Studio 2010 Web Development Overview 的阅读摘要,只是本人的学习记录,并非完整翻译,仅 ...

  5. Visual Studio 2010中C++项目升级指南

    如何升级? Visual Studio 2010支持来自VC6.Visual Studio 2002.Visual Studio 2003.Visual Studio 2005和Visual Stud ...

  6. 用VB.NET(Visual Basic 2010)封装EXCEL VBA为DLL_COM组件(二)

    --将EXCEL VBA代码移植到VB.NET .NET是微软公司在2002年推出的全新编程框架,支持多种语言应用程序开发.使用Visual Basic在Microsoft .NET Framewor ...

  7. 微软发布Visual Studio 2010 SP1公测版

    微软今天宣布了Visual Studio 2010 SP1的Beta测试版,MSDN订阅用户即日起可以下载,普通用户则要等到明天.微软表示,SP1 Beta拥有"go live"许 ...

  8. 下载 Visual Studio 2010 (SP1) Service Pack 1

    本文协助广宣 提醒您  VS 2010 SP1(中文版,包含 x86 与 x64),容量很大! 1,519MB [Action 1] 请快快安装使用,并广为周知! [Action 2] 若你是书籍作者 ...

  9. Visual Studio 2010 sp1介绍与下载

    Visual Studio 2010 SP1适用于Visual Studio 2010的所有版本,其改进如下: 1. 采用了新的帮助查看器: 2. 提供了更好的平台支持: 3. 新增了对Silverl ...

最新文章

  1. 干货|全面解析知识图谱:一种帮助通向强AI的数据科学技术
  2. 最大后验概率估计算法
  3. 搭建rabbitmq的docker集群
  4. lvs增加并发连接,解决因为哈希表过小导致软中断过高问题
  5. LeetCode-234. 回文链表(C语言)
  6. python列表输出斐波那契数列_Python|运用列表求斐波那契数列
  7. linux实现单机qq_Linux后台服务器开发——Linux下进程间通信的方式有哪些?
  8. XUbuntu20.04开机logo定制,主题修改启动背景
  9. linux常用的搜索命令
  10. 多个jQuery版本如何共存
  11. IText与pdfObject.js在线展示后台生成pdf文件流
  12. JBoss Tools 4.5.3.Final安装及下载
  13. docker,deamon.json文件说明
  14. jsp层级选择器_jQuery 选择器
  15. 打车类app怎么获取司机位置 开发_哈萨克斯坦的“滴滴打车-yandex taxi”有了它城市内任我行...
  16. 文本分析 | 管理层讨论信息含量原理与代码实现
  17. Dell服务器IPMI工具远程唤醒开机
  18. 谈谈Android个人开发者的现状
  19. 使用VS进行SqlServer数据库架构比较
  20. oracle的监听日志满了,对于Oracle监听日志定期清理

热门文章

  1. node.js的开发流程_Node.js子流程:您需要了解的一切
  2. 如何一起破解图形化Python调试器
  3. 如何通过中序和层序序列建立二叉树
  4. 1045 Favorite Color Stripe(LCS解法) 需再理解
  5. Java培训哪家机构好
  6. 《代码敲不队》第八次团队作业:Alpha冲刺 第二天
  7. 配置linux-Fedora系统下iptables防火墙
  8. 物联网技术正颠覆传统医疗行业
  9. 在python中调用js或者nodejs要使用PyExecJs第三方包。
  10. Oracle数据库文件坏块损坏的恢复方法