注意:这个问题涉及C++ 11.C++ 17(或更高版本)中相同问题的答案可能已经改变.详情如下:
当我们想要锁定多个时std::mutex,我们使用std::lock().但std::lock()不提供RAII功能.
当我们想以std::mutexRAII方式锁定时,我们使用std::lock_guard.但std::lock_guard不能std::mutex安全地锁定多个's.
有没有办法利用这两种方法的优势,以std::mutexRAII的方式锁定多个?
从这个问题我明白这std::scoped_lock是“一个严格的高级版本std::lock_guard”。
从这个问题我明白“std::lock_guard和std::unique_lock是一样的”,除了std::unique_lock有一些额外的功能(例如try_lock),但需要一些额外的开销。
与std::scoped_lock相比如何std::unique_lock?
我希望通过这个问题回答一些相关的问题。
std::scoped_lock和之间有什么区别std::unique_lock?std::scoped_lock而不是std::unique_lock?std::unique_lock而不是std::scoped_lock?std::scoped_lock实现 的一些附加功能std::unique_lock?我一直试图让一个项目摆脱每个boost参考并切换到纯C++ 11.
有一次,创建了线程工作者,它等待一个障碍来给出'go'命令,完成工作(通过N个线程传播)并在所有这些完成时同步.基本思想是主循环给出了go命令(boost :: barrier .wait())并等待具有相同函数的结果.
我在一个不同的项目中实现了一个基于Boost版本的定制Barrier,一切都运行得很好.实施如下:
Barrier.h:
class Barrier {
public:
Barrier(unsigned int n);
void Wait(void);
private:
std::mutex counterMutex;
std::mutex waitMutex;
unsigned int expectedN;
unsigned int currentN;
};
Run Code Online (Sandbox Code Playgroud)
Barrier.cpp
Barrier::Barrier(unsigned int n) {
expectedN = n;
currentN = expectedN;
}
void Barrier::Wait(void) {
counterMutex.lock();
// If we're the first thread, we want an extra lock at our disposal
if (currentN == expectedN) {
waitMutex.lock();
}
// Decrease thread counter
--currentN;
if (currentN == 0) {
currentN = expectedN;
waitMutex.unlock(); …Run Code Online (Sandbox Code Playgroud) 我找到了以下2段代码:
http://en.cppreference.com/w/cpp/thread/lock
void assign_lunch_partner(Employee &e1, Employee &e2)
{
// use std::lock to acquire two locks without worrying about
// other calls to assign_lunch_partner deadlocking us
{
// m is the std::mutex field
std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);
std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);
std::lock(lk1, lk2);
// ...
}
}
Run Code Online (Sandbox Code Playgroud)http://www.amazon.com/C-Concurrency-Action-Practical-Multithreading/dp/1933988770
void swap(X& lhs, X&rhs){
if(&lhs == &rhs)
return;
// m is the std::mutex field
std::lock(lhs.m, rhs.m);
std::lock_guard<std::mutex> lock_a(lhs.m, std::adopt_lock);
std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock);
swap(lhs.some_detail, rhs.some_detail);
}
Run Code Online (Sandbox Code Playgroud)我想问一下使用2个版本中的任何一个有什么区别和后果?(先锁定或首先创建std::lock_guard或std::unique_lock?)
我有 mailBox 类,在线程和线程之间共享发送和接收方法:线程 1 发送消息,线程 2 和 3 接收消息,我必须如何使用互斥锁来同步它?
我尝试过的任何组合都没有成功。
std::mutex g_lock; //in global
void sendMessage(Message msg) {
if (g_lock.try_lock()) {
this_thread::sleep_for(100ms); // DELAY
messages->push_back(msg);
g_lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
Receive方法相同
完整代码:https : //pastebin.com/7y2RC5br
此代码也无法调试,因为延迟会更改代码的逻辑。
代码的正确逻辑:线程2/3尝试锁定并读取消息,获取空然后解锁线程1尝试锁定并发送消息然后解锁线程2/3尝试锁定并读取消息,获取消息并写入文件然后解锁
当我从线程 2/3 尝试互斥锁的 try_lock 时,我一直在不断阻塞线程,并且线程 1 在所有线程 2/3 之后一直在工作。
线程具有以下控制流程:
mutex.lock()
if (condition) {
// do synced things
mutex.unlock();
// do parallel things
} else {
// do other synced things
mutex.unlock();
// do other parallel things
}
Run Code Online (Sandbox Code Playgroud)
注意这四个do部分如何执行不同的事情.
如何将直接调用替换为锁定和解锁std::lock_guard而改为使用?