简体   繁体   English

用boost :: lock_guard进行线程饥饿

[英]thread starvation with boost::lock_guard

i am trying to learn the boost library and was going through examples of boost::thread. 我正在尝试学习Boost库,并正在研究boost :: thread的示例。

The example below illustrates the usage of the boost::lock_guard for thread synchronization, ensuring that the access to std::cout is not concurrent: 下面的示例说明了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();
}

The results where pretty much what one would expect, ie alternating messages by the two threads printed: 结果几乎是人们所期望的,即通过打印的两个线程交替显示消息:

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
...

However, a small modification -- moving the wait call inside the scope of the lock guard -- led to a surprise: 然而,一个小的修改-移动锁定挡板的范围等待呼叫-导致了一个惊喜:

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;
    }

Now either thead1 or thread2 wins the initial "race" for the mutex and then wins again and again on each loop iteration, thereby starving the other thread! 现在,thead1或thread2赢得互斥量的初始“竞争”,然后在每次循环迭代中一次又一次获胜,从而使另一个线程饿死!

Example output: 输出示例:

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

Can anybody please explain why this is the case? 谁能解释为什么会这样吗?

This is because after the lock is acquired the wait call causes the second thread to begin executing. 这是因为在获取锁定后,等待调用导致第二个线程开始执行。 Since the second thread cannot acquire the lock it goes into a wait-state until the lock is available. 由于第二个线程无法获取锁定,因此它将进入等待状态,直到锁定可用为止。 In your case the lock does not become available until the first thread completes it's loop. 在您的情况下,只有在第一个线程完成循环之前,锁才变得可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM