簡體   English   中英

用boost :: lock_guard進行線程飢餓

[英]thread starvation with boost::lock_guard

我正在嘗試學習Boost庫,並正在研究boost :: thread的示例。

下面的示例說明了boost :: lock_guard用於線程同步的用法,確保對std :: cout的訪問不是並發的:

#include <boost/thread.hpp>
#include <boost/format.hpp>
#include <iostream>

void wait(const int secs) {
    boost::this_thread::sleep(boost::posix_time::seconds(secs));
}

boost::mutex mutex;

void thread1() {
    for (int i = 0; i < 10; ++i) {
        wait(1); // <-- all works fine if wait is placed here
        boost::lock_guard<boost::mutex> lock(mutex);
        std::cout << boost::format("thread A here %d\n") % i ;
    }
}

void thread2() {
    for (int i = 0; i < 10; ++i) {
        wait(1); //  <-- all works fine if wait is placed here
        boost::lock_guard<boost::mutex> lock(mutex);
        std::cout << boost::format("thread B here %d\n") % i;
    }

}

int main() {
    boost::thread t1(thread1);
    boost::thread t2(thread2);
    t1.join();
    t2.join();
}

結果幾乎是人們所期望的,即通過打印的兩個線程交替顯示消息:

thread A here 0
thread B here 0
thread A here 1
thread B here 1
thread A here 2
thread B here 2
thread A here 3
thread B here 3
thread A here 4
thread B here 4
...

然而,一個小的修改-移動鎖定擋板的范圍等待呼叫-導致了一個驚喜:

void thread1() {
    for (int i = 0; i < 10; ++i) {
        boost::lock_guard<boost::mutex> lock(mutex);
        wait(1); // <== !
        std::cout << boost::format("thread A here %d\n") % i ;
    }
}

void thread2() {
    for (int i = 0; i < 10; ++i) {
        boost::lock_guard<boost::mutex> lock(mutex);
        wait(1);  // <== !
        std::cout << boost::format("thread B here %d\n") % i;
    }

現在,thead1或thread2贏得互斥量的初始“競爭”,然后在每次循環迭代中一次又一次獲勝,從而使另一個線程餓死!

輸出示例:

thread B here 0
thread B here 1
thread B here 2
thread B here 3
thread B here 4
thread B here 5
thread B here 6
thread B here 7
thread B here 8
thread B here 9
thread A here 0
thread A here 1
thread A here 2
thread A here 3
thread A here 4
thread A here 5
thread A here 6
thread A here 7
thread A here 8
thread A here 9

誰能解釋為什么會這樣嗎?

這是因為在獲取鎖定后,等待調用導致第二個線程開始執行。 由於第二個線程無法獲取鎖定,因此它將進入等待狀態,直到鎖定可用為止。 在您的情況下,只有在第一個線程完成循環之前,鎖才變得可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM