本文主要介绍线程间共享数据的保护机制,主要内容是互斥量的介绍。
I、使用互斥量保护共享数据
1.1 lock 与 lock_guard
C++11中通过实例化std::mutex
创建互斥量,通过调用成员函数lock()
进行上锁,调用unlock()
进行解锁。
同样还提供了一个RAII语法的模板类std::lock_guard
,会在构造的时候提供已锁的互斥量,并在析构的时候进行解锁,从而保证了一个已锁的互斥量总是被正确的解锁。
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
#include<algorithm>
using namespace std;
//使得两个函数中对数据的访问时互斥的,list_contains不可能看到正在被add_to_list修改的列表
std::mutex some_mutex;
std::list<int> some_list;
void add_to_list(int new_value) {
std::lock_guard<mutex> guard(some_mutex); //用于在push_back的时候进行保护
some_list.push_back(new_value);
}
bool list_contains(int value_to_find) {
std::lock_guard<mutex> guard(some_mutex); //用于在find的时候进行保护
return find(some_list.begin(), some_list.end(), value_to_find);
}
1.2 unique_lock
unique_lock
使用起来要比lock_guard
更加灵活。首先,可将adopt_lock
作为第二个参数传入构造函数,对互斥量进行管理;也可以将defer_lock
作为第二个参数传递进去,表明互斥量应保持解锁状态,等等。
【参考】
[1] 《C++ Concurrency In Action》
网友评论