std::lock整体上是以如下步骤进行的
假设有锁m0 m1 m2 … m_end
- 从0索引开始lock
- 用try_lock对剩下的锁从m_0到m_end开始按顺序进行尝试,锁过的跳过,直到完全成功跳转到步骤5或失败于某个锁 m_i
- 释放之前的所有锁,调用yield放弃cpu
- 从m_i锁进行lock,转到步骤2
- 成功锁完全部,函数返回

//Mutex_pf.h
#pragma once
#include <mutex>
#include <string>
class Mutex_pf
{
private:
static int COUNT;
std::mutex mutex;
std::string name;
public:
Mutex_pf(std::string _name="");
~Mutex_pf() = default;
void lock();
void unlock();
bool try_lock();
};
//Mutex_pf.cpp
#include "Mutex_pf.h"
#include <iostream>
using std::cout;
int Mutex_pf::COUNT = 0;
Mutex_pf::Mutex_pf(std::string _name)
{
if (_name == "") {
this->name = std::to_string(COUNT++);
}
else {
this->name = _name;
}
}
void Mutex_pf::lock()
{
this->mutex.lock();
cout << std::this_thread::get_id() << " " << name << " lock\n";
}
bool Mutex_pf::try_lock()
{
if (this->mutex.try_lock()) {
cout << std::this_thread::get_id() << " " << name << " try_lock success\n";
return true;
}
else {
cout << std::this_thread::get_id() << " " << name << " try_lock false\n";
return false;
}
}
void Mutex_pf::unlock()
{
this->mutex.unlock();
cout << std::this_thread::get_id() << " " << name << " unlock\n";
}
#include <Windows.h>
#include "Mutex_pf.h"
template<typename T, size_t... N>
auto lock_vector_core(vector<T>& vec, std::integer_sequence<size_t, N...>) {
std::lock(vec[N]...);
}
//代理调用,简化接口,用make_integer_sequence来生成...N序列
template<typename T,size_t N>
auto lock_vector(vector<T>& vec) {
return lock_vector_core<>(vec, std::make_integer_sequence<size_t, N>{});
}
int main() {
vector<Mutex_pf> mutexs(10);
int i = 2;
mutexs[i].lock();
mutexs[6].lock();
std::thread t([&]() {
lock_vector<Mutex_pf, 10>(mutexs);
for (auto& m : mutexs) {
m.unlock();
}
});
Sleep(5000);
mutexs[i].unlock();
Sleep(5000);
mutexs[6].unlock();
t.join();
return 0;
}
29172 2 lock 29172 6 lock//主线程的加锁 9360 0 lock //子线程从0开始进行lock 9360 1 try_lock success 9360 2 try_lock false //锁2失败 9360 1 unlock 9360 0 unlock//释放之前的锁 29172 2 unlock //主线程释放锁2 9360 2 lock //从锁2开始进行重新上锁 9360 0 try_lock success 9360 1 try_lock success 9360 3 try_lock success 9360 4 try_lock success 9360 5 try_lock success 9360 6 try_lock false //上面按顺序进行加锁,到锁6失败 9360 3 unlock 9360 4 unlock 9360 5 unlock 9360 0 unlock 9360 1 unlock 9360 2 unlock //释放之前的锁 29172 6 unlock //主线程释放锁6 9360 6 lock //从锁6开始lock 9360 0 try_lock success 9360 1 try_lock success 9360 2 try_lock success 9360 3 try_lock success 9360 4 try_lock success 9360 5 try_lock success 9360 7 try_lock success 9360 8 try_lock success 9360 9 try_lock success //还是按顺序来进行try_lock。这次全部成功 9360 0 unlock 9360 1 unlock 9360 2 unlock 9360 3 unlock 9360 4 unlock 9360 5 unlock 9360 6 unlock 9360 7 unlock 9360 8 unlock 9360 9 unlock//释放锁保证程序能正确退出