(C ++ 11) |
関連付けられた条件変数提供 のstd :: unique_lockのを |
condition_variable
(C ++ 11)
のstd ::条件変数関連unique_lockのが設けられ
例
condition_variable
組み合わせて使用されている のstd ::ミューテックス スレッド間通信を容易にします。
実施例1つの
結合糸の間の通信を容易にするために使用condition_variableとstd ::ミューテックス。
待機関数はstd :: condition_variableオブジェクトが呼び出されると、それは(のstd ::経由ミューテックス)現在のスレッドをロックするためにはstd :: unique_lockのを使用しています。別のスレッドが現在のスレッドを目覚めさせるために同じのstd :: condition_variableオブジェクトに通知関数を呼び出すまで、現在のスレッドは常にブロックされます。
std :: condition_variable定期的に使用するのstd :: unique_lockの<はstd ::ミューテックス>待ち、追加のロック可能なタイプを使用して、必要に応じて、使用のstd :: condition_variable_anyクラスは、後にここで言及されることがあり、はstd :: condition_variable_any使用を。
// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
//std::this_thread::sleep_for(std::chrono::seconds(1));
// wait until main() sends data
std::unique_lock<std::mutex> lk(m);
std::cout << "thread lk.lock\n";
// here m will be unlocked,and will wait other thread notify ,if recive other thread notify,this thread will go on.
cv.wait(lk, [] {return ready; });
// after the wait, we own the lock
std::cout << "Worker thread is processing data\n";
data += " after processing";
// send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completed\n";
// Manual unlocking is done befor nodifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}
int main()
{
std::thread worker(worker_thread);
data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
std::cout << "main lk.lock\n";
ready = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();
// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] {return processed; });
}
std::cout << "Back in main(),data = " << data << '\n';
worker.join();
return 0;
}
結果:
cv.wait()ロック解除をロックして、別のスレッドが通知を送信する場合、それが継続すると、ロックをロックします、自分のを待ちます。
例2
// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <queue>
class condvarQueue
{
std::queue<int> produced_nums;
std::mutex m;
std::condition_variable cond_var;
bool done = false;
bool notified = false;
public:
void push(int i)
{
std::unique_lock<std::mutex> lock(m);
produced_nums.push(i);
notified = true;
cond_var.notify_one();
}
template<typename Consumer>
void consume(Consumer consumer)
{
std::unique_lock<std::mutex> lock(m);
while (!done) {
while (!notified) {
cond_var.wait(lock);
}
while (!produced_nums.empty()) {
consumer(produced_nums.front());
produced_nums.pop();
}
notified = false;
}
}
void close()
{
done = true;
notified = true;
cond_var.notify_one();
}
};
int main()
{
condvarQueue queue;
std::thread producer([&]() {
for (int i = 0; i < 5; i++) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "producing" << i << '\n';
queue.push(i);
}
queue.close();
});
std::thread consumer([&]() {
queue.consume([](int input) {
std::cout << "consuming " << input << '\n';
});
});
producer.join();
consumer.join();
return 0;
}
結果:
producing0
0消費
producing1
消費を。1
producing2は
2消費
producing3
消費を。3
producing4
消費。4
任意のキーを押して続行し。
例3 .notify_all
// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <queue>
std::condition_variable cv;
std::mutex cv_m;// This mutex is used for three purposes
// 1) to synchronize accesses to i
// 2) to synchronize accesses to std::cerr
// 3) for the condition variable cv
int i = 0;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cerr << "Waiting... \n";
cv.wait(lk, [] {return i == 1; });// only when i ==1, wait will return
std::cerr << "...finished waiting.i == 1\n";
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lk(cv_m);
std::cerr << "Notifying...\n";
}
cv.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lk(cv_m);
i = 1;
std::cerr << "Notifying again...\n";
}
cv.notify_all();
}
int main()
{
std::thread t1(waits), t2(waits), t3(waits), t4(signals);
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
//output
/*
Waiting...
Waiting...
Waiting...
Notifying...
Notifying again...
...finished waiting.i == 1
...finished waiting.i == 1
...finished waiting.i == 1
请按任意键继续. . .
*/