Подтвердить что ты не робот

Как использовать /create unique_lock в С++?

Пожалуйста, может кто-нибудь объяснить, как использовать и создать уникальный_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();
}
4b9b3361

Ответ 1

std::unique_lock используйте шаблон RAII.

Если вы хотите заблокировать мьютекс, вы создаете локальную переменную типа std::unique_lock, передающую параметр mutex в качестве параметра. Когда unique_lock будет построен, он заблокирует мьютекс, и он будет разрушен, он разблокирует мьютекс. Что еще более важно: если выбрано исключение, вызывается std::unique_lock деструктор , и поэтому мьютекс будет разблокирован.

Пример:

#include<mutex>
int func() {
    int a = 3;
    { //Critical session
        std::unique_lock<mutex> lock(my_mutex);
        some_shared_var += a;
    } //End of critical session
}        

Ответ 2

Более подробный пример кода с использованием переменных условия:

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

Ответ 3

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
}

Обратите внимание, что я заменил if на while для учета ложных следов от вызова wait().

Ответ 4

В этом случае, я думаю, все, что вам нужно сделать, это:

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