45

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

4 に答える 4

65

std::unique_lockRAIIパターンを使用します。

ミューテックスをロックする場合は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
}        
于 2013-02-05T14:06:35.597 に答える
10

条件変数を使用したより詳細なサンプルコード:

#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();
}
于 2016-09-14T08:15:49.083 に答える
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
}

呼び出しからの誤ったウェイクを考慮しifて、をに置き換えたことに注意してください。whilewait()

于 2013-02-05T15:56:34.490 に答える
-5

この場合、あなたがする必要があるのは次のことだけだと思います。

m.lock();
// Critical section code
m.unlock();
于 2013-02-05T14:01:20.417 に答える