如何在 C++ 中使用/创建 unique_lock?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14709233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use/create unique_lock in c++?
提问by SagittariusA
Please, can anybody explain how to use and create an unique_lock in c++? It should be used both to get mutual exclusion to any procedure of the monitor and to be able to perform wait() on the condition variable...I'm not understanding from the documentation how I am supposed to create it. Is necessary a mutex? Here is a pseudo-code:
拜托,有人可以解释如何在 C++ 中使用和创建 unique_lock 吗?应该使用它来获得监视器的任何程序的互斥,并能够对条件变量执行 wait() ......我不明白文档中应该如何创建它。有必要互斥吗?这是一个伪代码:
/* compile with g++, flags -std=c++0x -lpthread */
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <string.h>
#include <unistd.h>
class monitorTh {
private:
std::mutex m;
std::condition_variable waitP;
std::condition_variable waitC;
char element[32];
std::unique_lock::unique_lock l;
public:
void produce(char* elemProd) {
l.lock();
if (/*already_present_element*/) {
waitP.wait(l);
}
else {/*produce element*/}
l.unlock();
}
void consume() {
/*something specular*/
}
};
int main(int argc, char* argv[]) {
monitorTh* monitor = new monitorTh();
char prodotto[32] = "oggetto";
std::thread producer([&]() {
monitor->produce(prodotto);
});
std::thread consumer([&]() {
monitor->consume();
});
producer.join();
consumer.join();
}
回答by André Puel
std::unique_lock
use the RAIIpattern.
std::unique_lock
使用RAII模式。
When you want to lock a mutex, you create a local variable of type std::unique_lock
passing the mutex as parameter. When the unique_lock is constructed it will lock the mutex, and it gets destructed it will unlock the mutex. More importantly: If a exceptions is thrown, the std::unique_lock
destructer willbe called and so the mutex will be unlocked.
当您想要锁定互斥锁时,您可以创建一个局部变量,std::unique_lock
该变量将互斥锁作为参数传递。当 unique_lock 被构造时,它将锁定互斥锁,并且它被破坏将解锁互斥锁。更重要的是:如果抛出异常,将调用std::unique_lock
析构函数,从而解锁互斥锁。
Example:
例子:
#include<mutex>
int some_shared_var=0;
int func() {
int a = 3;
{ //Critical section
std::unique_lock<std::mutex> lock(my_mutex);
some_shared_var += a;
} //End of critical section
}
回答by Anthony Williams
std::unique_lock<std::mutex>
holds a lock on a separate std::mutex
object. You associate the lock object with the mutex by passing it in the constructor. Unless you specify otherwise, the mutex will be immediately locked. If the lock object holds the lock when it is destroyed then the destructor will release the lock. Typically, the std::unique_lock<std::mutex>
object will thus be a local variable, declared at the point where you wish to acquire the lock.
std::unique_lock<std::mutex>
持有一个单独的std::mutex
对象的锁。通过在构造函数中传递锁对象与互斥锁相关联。除非您另外指定,互斥锁将被立即锁定。如果锁对象在销毁时持有锁,那么析构函数将释放锁。通常,该std::unique_lock<std::mutex>
对象因此将是一个局部变量,在您希望获取锁的地方声明。
In your case, the produce()
function could be written like this:
在您的情况下,该produce()
函数可以这样编写:
void produce(char* elemProd) {
std::unique_lock<std::mutex> lk(m); // lock the mutex
while (/*already_present_element*/) { // condition variable waits may wake spuriously
waitP.wait(lk);
}
{/*produce element*/}
// lk releases the lock when it is destroyed
}
Note that I have replaced the if
with a while
to account for spurious wakes from the wait()
call.
请注意,我已将 替换为if
awhile
以说明来自wait()
呼叫的虚假唤醒。
回答by Babra Cunningham
A more detailed sample code using condition variables:
使用条件变量的更详细示例代码:
#include<mutex>
std::mutex(mu); //Global variable or place within class
std::condition_variable condition; //A signal that can be used to communicate between functions
auto MyFunction()->void
{
std::unique_lock<mutex> lock(mu);
//Do Stuff
lock.unlock(); //Unlock the mutex
condition.notify_one(); //Notify MyOtherFunction that this is done
}
auto MyOtherFunction()->void
{
std::unique_lock<mutex> lock(mu);
condition.wait(lock) //Wait for MyFunction to finish, a lambda can be passed also to protects against spurious wake up e.g (lock,[](){return *some condition*})
lock.unlock();
}
回答by DigitalInBlue
In this case, I think all you need to do is:
在这种情况下,我认为您需要做的就是:
m.lock();
// Critical section code
m.unlock();