如何在c++中使用/创建unique_lock

How to use/create unique_lock in c++?

本文关键字:创建 unique lock c++      更新时间:2023-10-16

有人能解释一下如何在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();
}

std::unique_lock使用RAII模式。

当您想要锁定互斥体时,您可以创建一个类型为std::unique_lock的本地变量,将互斥体作为参数传递。当构造unique_lock时,它将锁定互斥锁,当它被破坏时,它会解锁互斥锁。更重要的是:如果抛出异常,std::unique_lock析构函数将被调用,因此互斥锁将被解锁。

示例:

#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
}        

使用条件变量的更详细的示例代码:

#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();
}

std::unique_lock<std::mutex>在一个单独的std::mutex对象上持有一个锁。通过在构造函数中传递锁对象,可以将其与互斥对象相关联。除非您另有指定,否则互斥对象将立即被锁定。如果锁对象在被销毁时持有锁,则析构函数将释放锁。因此,std::unique_lock<std::mutex>对象通常是一个局部变量,在您希望获取锁的位置声明。

在您的情况下,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
}

请注意,我已经用while替换了if,以说明来自wait()调用的虚假唤醒。

在这种情况下,我认为您所需要做的就是:

m.lock();
// Critical section code
m.unlock();