1. 程式人生 > >對C++11條件變數的理解(邏輯)

對C++11條件變數的理解(邏輯)

之前對條件變數一直抱有疑惑,通過互斥鎖已經能夠保證同一時刻只有一個執行緒訪問共享區資源了,那還要用條件變數幹什麼呢?說到這裡,解惑來源於這篇文章c++11執行緒之條件變數condition_variable,互斥鎖只能保證執行緒不同時訪問共享區資源,但是訪問的順序是雜亂無章的,而條件變數是為了保證執行緒操作按順序進行。
還有,條件變數std::condition_variable::wait(std::unique& lck)函式在呼叫的時候會釋放鎖lck(呼叫lck.unlock()),在其他執行緒呼叫notify_all()(此處也可以是其他喚醒函式)後執行緒停止阻塞,繼續執行,但是此時執行緒使用的wait()會將lck恢復到阻塞之前的狀態,也就是加鎖,之前一直百思不得其解,還一直糾結這個程式碼為什麼沒有死鎖`#include // std::cout

include // std::thread

include // std::mutex, std::unique_lock

include // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

int cargo = 0; // shared value by producers and consumers

void consumer()
{
std::unique_lock < std::mutex > lck(mtx);
while (cargo == 0)
cv.wait(lck);//阻塞
std::cout << cargo << ‘\n’;
cargo = 0;
}
void producer(int id)
{
//std::unique_lock < std::mutex > lck(mtx);
cargo = id;
cv.notify_one();//喚醒某一個執行緒
}

int main()
{
std::thread consumers[10], producers[10];

// spawn 10 consumers and 10 producers:
for (int i = 0; i < 10; ++i) 
{
    consumers[i] = std::thread(consumer);
    producers[i] = std::thread(producer, i + 1);
}

// join them back:
for (int i = 0; i < 10; ++i) {
    producers[i].join();
    consumers[i].join();
}
return 0;

}`,其實,條件變數在使得當前執行緒阻塞時,是擁有了一個鎖的,如果不釋放該鎖,則當前執行緒會阻塞,而且其他執行緒也會因為該鎖二阻塞,這就導致所有執行緒均阻塞,這是我們不想看到的結果,我們需要其他執行緒在當前執行緒阻塞時繼續執行,從而觸發當前執行緒被喚醒;在當前執行緒被喚醒後,需要加鎖,這是因為當前執行緒已經進入資源共享區,需要放置其他執行緒也進來訪問,所以加鎖,如此便保證了順序(邏輯上的順序)訪問。