互斥

c++通过std::mutex实现锁机制,确保多线程下只有一个进入临界区

1
2
3
4
#include <mutex>
std::mutex mtx;
mtx.lock();
mtx.unlock();

层级锁

自定义锁添加权重来保证每次加锁顺序和解锁顺序,数值越大权重越高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class hmutex {
public:
hmutex(unsigned value):cur(val),pre(0)
void lock(){
if(cur <= val) std::logic_error("faild");
mtx.lock();
pre=cur,cur=val;
}
void unlock(){
if(cur != val) std::logic_error("faild");
mtx.unlock();
cur=pre;
}
private:
std::mutex mtx;
unsigned val;
unsigned pre;
static unsigned cur;
};

share_mutex

C++17新增了共享锁用来访问共享数据,实现读写锁,C++14提供share_timed_mutex,不同的是在获取锁时提供了超时机制

lock(), try_lock()

lock_shared(), try_lock_shared()

1
2
3
std::shared_mutex mtx;
std::shared_lock<std::shared_mutex> sl(mtx);
std::lock_guard<std::shared_mutex> gl(mtx);

RAII锁

lock_guard

构造析构时自动加锁解锁,因此当中途return或退出时会自动释放锁

1
2
3
{
std::lock_guard<std::mutex> lock(mtx);
}

c++容器不是线程安全的,因此每次操作都需要加锁

unique_lock

比lock_guard更加灵活,可以手动解锁,服务细粒度场景

支持同条件变量一起使用,一旦mutex被unique_lock管理就不能通过mutex加锁解锁

使用owns_lock()判断有无获取锁

可以延迟加锁std::unique_lock<std::mutex>(mtx,std::defer_lock)

mutex不支持移动和拷贝,但可以通过unique_lock进行转移

scope_lock

c++17新特性,可对多个互斥量同时加锁

1
2
3
{
std::scople_lock lock(mtx1, mtx2);
}