条件変数とミューテックスでの使用法を理解するのに苦労しています。コミュニティが助けてくれることを願っています。私はwin32のバックグラウンドを持っているので、CRITICAL_SECTION、HANDLE、SetEvent、WaitForMultipleObjectなどで使用されていることに注意してください.
これは、c++11 標準ライブラリを使用した同時実行の最初の試みです。これは、ここにあるプログラム例の修正版です。
#include <condition_variable>
#include <mutex>
#include <algorithm>
#include <thread>
#include <queue>
#include <chrono>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
std::queue<unsigned int> nNumbers;
std::mutex mtxQueue;
std::condition_variable cvQueue;
bool m_bQueueLocked = false;
std::mutex mtxQuit;
std::condition_variable cvQuit;
bool m_bQuit = false;
std::thread thrQuit(
[&]()
{
using namespace std;
this_thread::sleep_for(chrono::seconds(7));
// set event by setting the bool variable to true
// then notifying via the condition variable
m_bQuit = true;
cvQuit.notify_all();
}
);
std::thread thrProducer(
[&]()
{
using namespace std;
int nNum = 0;
unique_lock<mutex> lock( mtxQuit );
while( ( ! m_bQuit ) &&
( cvQuit.wait_for( lock, chrono::milliseconds(10) ) == cv_status::timeout ) )
{
nNum ++;
unique_lock<mutex> qLock(mtxQueue);
cout << "Produced: " << nNum << "\n";
nNumbers.push( nNum );
}
}
);
std::thread thrConsumer(
[&]()
{
using namespace std;
unique_lock<mutex> lock( mtxQuit );
while( ( ! m_bQuit ) &&
( cvQuit.wait_for( lock, chrono::milliseconds(10) ) == cv_status::timeout ) )
{
unique_lock<mutex> qLock(mtxQueue);
if( nNumbers.size() > 0 )
{
cout << "Consumed: " << nNumbers.front() << "\n";
nNumbers.pop();
}
}
}
);
thrQuit.join();
thrProducer.join();
thrConsumer.join();
return 0;
}
これについていくつか質問があります。
「std::condition_variable を待機するスレッドは、最初に std::unique_lock を取得する必要がある」と読みました。
したがって、いつ終了が通知されたかを示す {quit mutex, condition variable & bool} があります。次のように、プロデューサー スレッドとコンシューマー スレッドはそれぞれ std::unique_lock を取得する必要があります。
std::unique_lock<std::mutex> lock(m_mtxQuit);
これは私を混乱させています。これにより、最初のスレッドで終了ミューテックスがロックされ、2 番目のスレッドがブロックされませんか? それが本当なら、最初のスレッドはどのようにしてロックを解放し、他のスレッドが開始できるようにするのでしょうか?
もう 1 つの質問: wait_for() 呼び出しを 0 秒待機するように変更すると、そのスレッドは枯渇します。誰か説明できますか?while ループを実行する前にブロックしないことを期待します (タイムアウトの代わりに no_timeout が recv されると仮定するのは正しいですか?)。
wait_for() を呼び出してゼロ時間を指定して、wait_for() 呼び出しがブロックされず、代わりに条件をチェックして続行するにはどうすればよいですか?
また、この件に関する優れた参考文献についても知りたいと思います。