将多线程作为并行的关键优点之一,在于它们之间简单直接地共享数据的能力。但当多个线程修改同一数据时,就很容易因为竞争而导致错误的执行结果。若所有线程只是进行读取操作,就没有问题。
1.认识std::mutex由C++标准提供的保护共享数据的最基本机制是互斥元/锁(mutex)(读缪特克斯)。在访问共享数据之前,锁定(lock)与该数据相关的互斥元,访问完成后,解锁(unlock)该互斥元。线程库会确保一个线程锁定某个互斥元后,其他试图锁定该互斥元的线程必须等待,直到之前的线程解锁。(如果需要递归锁定,可以使用 recursive_mutex )
可以通过在线手册查看该类接口 https://zh.cppreference.com/w/cpp/thread/mutex ,除了lock和unlock,还有一个try_lock方法:尝试锁定互斥,若互斥不可用则返回。需要注意的是,不要随意将受保护数据的指针或引用传递到锁的范围之外。
#include
std::mutex mtx;
int num;
void set(int i) {
mtx.lock();
num = i;
mtx.unlock();
}
int get() {
mtx.lock();
const int temp = num;
mtx.unlock();
return temp;
}
2.认识std::lock_guard
标准C++库还提供了std::lock_guard类模板,在构造时锁定给定的互斥元,析构时将互斥元解锁,从而保证锁定的互斥元始终被正确解锁。
#include
std::mutex mtx;
int num;
void set(int i) {
std::lock_guard guard(mtx);
num = i;
}
int get() {
std::lock_guard guard(mtx);
return num;
}
该类模板有两个构造函数:
explicit lock_guard( mutex_type& m ); 等效地调用 m.lock() ,若 m 不是递归互斥,且当前线程已占有 m 则行为未定义。
lock_guard( mutex_type& m, std::adopt_lock_t t ); 获得互斥 m 的所有权而不试图锁定它。若当前线程不占有 m 则行为未定义。
如果单单使用mutex和lock_guard还是比较简单的,毕竟接口就那么几个。下面的例子中,我构造了一个队列,一个线程写入操作,两个线程读取操作。
#include
#include
#include
#include
#include
//pair
#include
template
class ThreadQueue
{
public:
ThreadQueue() {}
~ThreadQueue() {}
void inqueue(const T& item) {
std::lock_guard guard(dataMutex);
//dataMutex.lock();
dataQueue.push(item);
//dataMutex.unlock();
}
std::pair dequeue() {
std::lock_guard guard(dataMutex);
//dataMutex.lock();
bool is_valid = false;
T item;
if (!dataQueue.empty()) {
is_valid = true;
item = dataQueue.front();
dataQueue.pop();
}
//dataMutex.unlock();
return std::make_pair(is_valid, item);
}
bool notEmpty() const {
return (!dataQueue.empty());
}
private:
std::mutex dataMutex;
std::queue dataQueue;
};
int main()
{
ThreadQueue my_queue;
int counter = 0;
bool working = true;
std::thread write_thread([&]() {
while (working) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
my_queue.inqueue(++counter);
std::cerr
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?