c++11 多线程 1

第3章 线程间共享数据

本章主要内容

  • 共享数据带来的问题                    
  • 使用互斥量保护数据
  • 数据保护的替代方案

保护共享数据结构的最基本的方式,是使用C++标准库提供的互斥量(mutex)。

清单3.1 使用互斥量保护列表     推荐 使用  lock_guard   不推荐使用 louck()与 unlouck()这样的方式

#include <list>
#include <mutex>
#include <algorithm>

std::list<int> some_list;    // 1
std::mutex some_mutex;    // 2
void add_to_list(int new_value){ std::lock_guard<std::mutex> guard(some_mutex); // 3 some_list.push_back(new_value); } bool list_contains(int value_to_find){ std::lock_guard<std::mutex> guard(some_mutex); // 4 return std::find(some_list.begin(),some_list.end(),value_to_find) != some_list.end();
}

这两个函数中对数据的访问是互斥的:list_contains()不可能看到正在被add_to_list()修改的列表。

虽然某些情况下,使用全局变量没问题,但在大多数情况下,互斥量通常会与保护的数据放在同一个类中,而不是定义成全局变量。这是面向对象设计的准则:将其放在一个类中,就可让他们联系在一起,也可对类的功能进行封装,并进行数据保护。在这种情况下,函数add_to_list和list_contains可以作为这个类的成员函数。互斥量和要保护的数据,在类中都需要定义为private成员,这会让访问数据的代码变的清晰,并且容易看出在什么时候对互斥量上锁。当所有成员函数都会在调用时对数据上锁,结束时对数据解锁,那么就保证了数据访问时不变量不被破坏。

当然,也不是总是那么理想,聪明的你一定注意到了:当其中一个成员函数返回的是保护数据的指针或引用时,会破坏对数据的保护。具有访问能力的指针或引用可以访问(并可能修改)被保护的数据,而不会被互斥锁限制。互斥量保护的数据需要对接口的设计相当谨慎,要确保互斥量能锁住任何对保护数据的访问,并且不留后门。










猜你喜欢

转载自www.cnblogs.com/zhangkele/p/9069849.html