C++编程 –安全并发访问容器元素

C++ 安全并发访问容器元素

2014-9-24 flyfish

标准库STL的vector, deque, list等等不是线程安全的
例如 线程1正在使用迭代器(iterator)读vector
线程2正在对该vector进行插入操作,使vector重新分配内存,这样就造成线程1中的迭代器失效

STL的容器
多个线程读是安全的,在读的过程中,不能对容器有任何写入操作
多个线程可以同时对不同的容器做写入操作。
不能指望任何STL实现来解决线程难题,必须手动做同步控制.

C++ 设计新思维》 下载见

C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码

读C++ Primer 之构造函数陷阱

读C++ Primer 之智能指针

读C++ Primer 之句柄类

将C语言梳理一下,分布在以下10个章节中:

Linux-C成长之路(一):Linux下C编程概要

Linux-C成长之路(二):基本数据类型

Linux-C成长之路(三):基本IO函数操作

Linux-C成长之路(四):运算符

Linux-C成长之路(五):控制流

Linux-C成长之路(六):函数要义

Linux-C成长之路(七):数组与指针

Linux-C成长之路(八):存储类,动态内存

Linux-C成长之路(九):复合数据类型

Linux-C成长之路(十):其他高级议题



方案1 对vector进行加锁处理

effective STL给出的Lock框架

template<typename Container> //一个为容器获取和释放互斥体的模板 
class Lock
{ //框架;其中的很多细节被省略了 
public:
 Lock(const Container& container) :c(container)
 { 
  getMutexFor(c);
  //在构造函数中获取互斥体
 }
 ~Lock()
 { 
  releaseMutexFor(c);
  //在析构函数中释放它
 }
private: const Container& c;
}; 

如果需要实现工业强度,需要做更多的工作。


方案2 微软的Parallel Patterns Library (PPL)


看MSDN
PPL 提供的功能

1 Task Parallelism: a mechanism to execute several work items (tasks) in parallel
任务并行:一种并行执行若干工作项(任务)的机制

2 Parallel algorithms: generic algorithms that act on collections of data in parallel
并行算法:并行作用于数据集合的泛型算法

3 Parallel containers and objects: generic container types that provide safe concurrent access to their elements
并行容器和对象:提供对其元素的安全并发访问的泛型容器类型


示例是对斐波那契数列(Fibonacci)的顺序计算和并行计算的比较

顺序计算是
使用 STL std::for_each 算法
结果存储在 std::vector 对象中。

并行计算是
使用 PPL Concurrency::parallel_for_each 算法
结果存储在 Concurrency::concurrent_vector 对象中。

// parallel-fibonacci.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <concurrent_vector.h>
#include <array>
#include <vector>
#include <tuple>
#include <algorithm>
#include <iostream>


using namespace Concurrency;
using namespace std;


// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>
__int64 time_call(Function&& f)
{
  __int64 begin = GetTickCount();
  f();
  return GetTickCount() - begin;
}


// Computes the nth Fibonacci number.
int fibonacci(int n)
{
  if(n < 2)
      return n;
  return fibonacci(n-1) + fibonacci(n-2);
}


int wmain()
{
  __int64 elapsed;


  // An array of Fibonacci numbers to compute.
  array<int, 4> a = { 24, 26, 41, 42 };


  // The results of the serial computation.
  vector<tuple<int,int>> results1;


  // The results of the parallel computation.
  concurrent_vector<tuple<int,int>> results2;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/b059785ceebdd894e45a89f0fa48c5da.html