-
std::unique_lock() noexcept; //可以構造一個空的std::unique_lock對象,此時並不擁有任何mutex
-
explicit std::unique_lock (mutex_type& m);//擁有mutex,並調用mutex.lock()對其上鎖
-
std::unique_lock (mutex_type& m, try_to_lock_t tag);//tag=try_lock表示調用mutex.try_lock()嘗試加鎖
-
std::unique_lock (mutex_type& m, defer_lock_t tag) noexcept;//tag=defer_lock表示不對mutex加鎖,只管理mutex,此時mutex應該是沒有加鎖的
-
std::unique_lock (mutex_type& m, adopt_lock_t tag);//tag=adopt_lock表示mutex在此之前已經被上鎖,此時unique_locl管理mutex
-
template <class Rep, class Period>
std::unique_lock (mutex_type& m, const chrono::duration<Rep,Period>& rel_time);//在一段時間rel_time內嘗試對mutex加鎖,mutex.try_lock_for(rel_time) -
template <class Clock, class Duration>
std::unique_lock (mutex_type& m, const chrono::time_point<Clock,Duration>& abs_time);//mutex.try_lock_until(abs_time)直到abs_time嘗試加鎖 -
std::unique_lock (const std::unique_lock&) = delete;//禁止拷貝構造
-
std::unique_lock (std::unique_lock&& x);//獲得x管理的mutex,此後x不再和mutex相關,x此後相當於一個默認構造的std::unique_lock,移動構造函數,具備移動語義,movable but not copyable
c++11多線程中的condition_variable
(條件變量) - A_Bo的博客 - CSDN博客
https://blog.csdn.net/li1615882553/article/details/86179781
wait函數
當前線程調用wait()
後將被阻塞並且函數會 解鎖 互斥量,如果使用lock_guard
則不能調用unlock
函數,所以這裏只能使用unique_lock
對象,直到另外某個線程調用notify_one
或者notify_all
喚醒當前線程;一旦當前線程獲得通知(notify),wait()
函數也是自動調用lock()
,同理不能使用lock_guard
對象。
如果wait沒有第二個參數,第一次調用默認條件不成立,直接解鎖互斥量並阻塞到本行,直到某一個線程調用notify_one
或notify_all
爲止,被喚醒後,wait
重新嘗試獲取互斥量,如果得不到,線程會卡在這裏,直到獲取到互斥量,然後無條件地繼續進行後面的操作
如果wait包含第二個參數,如果第二個參數不滿足,那麼wait
將解鎖互斥量並堵塞到本行,直到某一個線程調用notify_one
或notify_all
爲止,被喚醒後,wait
重新嘗試獲取互斥量,如果得不到,線程會卡在這裏,直到獲取到互斥量,然後繼續判斷第二個參數,如果表達式爲false,wait對互斥量解鎖,然後休眠,如果爲true,則進行後面的操作
- 1
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
std::mutex mutex_;
std::condition_variable condVar;
void tStart()
{
std::cout << "Wait 1" << std::endl;
std::unique_lock<std::mutex> lock(mutex_); // 2 進入後,會對mutex_進行加鎖
std::cout << "Enter 1" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "endSleep 1" << std::endl;
condVar.wait(lock); // 4 等待的時候,會釋放mutex_
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // 7 被喚醒後,則搶佔,進行休眠
std::cout << "Exit 1" << std::endl; // 8退出
}
void tWait()
{
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 1 讓tStart 先進
std::cout << "Wait 2" << std::endl;
std::unique_lock<std::mutex> lock(mutex_); // 3 第2步加鎖後,則會在此等待
std::cout << "Enter 2" << std::endl; // 5 在第4步釋放後,則立即進入,並對mutex_加鎖
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "Enter 2" << std::endl;
condVar.notify_one(); // 6 喚醒等待的線程,也只有一個線程在等待
}
int main()
{
std::thread threadStart(tStart);
std::thread threadWait(tWait);
threadStart.join();
threadWait.join();
return 0;
}
運行結果 :
Wait 1
Enter 1
Wait 2
endSleep 1
Enter 2
Enter 2
Exit 1
- 2
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
std::mutex mutex_;
std::condition_variable condVar;
bool dataReady;
void waitingForWork()
{
std::cout << "Waiting for waitingForWork." << std::endl;
std::unique_lock<std::mutex> lck(mutex_); // 2. 對mutex_加鎖
std::cout << "Enter A" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "Waiting...." << std::endl;
condVar.wait(lck, [] {return dataReady; }); // 3. 等待, 釋放mutex_
std::cout << "Waiting End" << std::endl; // 6.一直往下執行
std::cout << "->Processing shared data." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "Work done." << std::endl;
}
void setDataReady()
{
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 1. 讓 waitingForWork 線程先進
std::cout << " Waiting for setDataReady." << std::endl;
std::lock_guard<std::mutex> lck(mutex_);
std::cout << "Enter B" << std::endl; // 4 進入,並對mutex_加鎖, 並一直往下執行
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << " dataReady = true; " << std::endl;
dataReady = true;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "Sender: Data is ready." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
condVar.notify_one(); // 5. 喚醒,並結束此線程,釋放mutex_
}
int main() {
std::cout << std::endl;
std::thread t1(waitingForWork);
std::thread t2(setDataReady);
t1.join();
t2.join();
std::cout << std::endl;
return 0;
}
運行結果 :
Waiting for waitingForWork.
Enter A
Waiting for setDataReady.
Waiting....
Enter B
dataReady = true;
Sender: Data is ready.
Waiting End
->Processing shared data.
Work done.