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

Sag*_*usA 33 c++ locking c++11

请问,任何人都可以解释如何在c ++中使用和创建unique_lock吗?它应该被用来既能获得互斥到显示器的任何程序,并能在条件变量进行等待()...我不是从文档了解我应该如何创建它.是必要的互斥?这是一个伪代码:

/* 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();
}
Run Code Online (Sandbox Code Playgroud)

And*_*uel 41

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
}        
Run Code Online (Sandbox Code Playgroud)

  • @ProQ它是在堆栈上创建的。如果您使用new关键字,则在离开范围时不会被破坏。 (4认同)
  • 为什么不需要“new”关键字来创建锁? (2认同)

Ant*_*ams 6

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
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经将ifa 替换while为来自wait()呼叫的虚假唤醒.


Bab*_*ham 6

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

#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();
}
Run Code Online (Sandbox Code Playgroud)

  • 显式解锁是不必要的.查看unique_lock()的行为方式. (4认同)
  • @pcodex 在第二种情况下,我同意,但如果性能很重要,第一种情况对我来说似乎是有效的。否则,可能会在互斥体解锁之前通知该条件。或者我错过了什么? (2认同)