使用条件变量而不是lock_guard

时间:2015-07-07 17:01:02

标签: c++ multithreading condition-variable

我有一个简单的程序,我想输出数字1-100,一个线程输出所有奇数,另一个输出所有偶数。使用lock_guard,这是一项非常简单的任务。代码如下:

    #include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>

std::mutex m;


void print_numbers(int i)
{
    for (i; i <= 100; i++)
    {
        std::lock_guard<std::mutex> locker(m);
        std::cout << i << std::endl;
        ++i;
    }
}

int main()
{
    std::thread t1(print_numbers, 0);
    std::thread t2(print_numbers, 1);
    t1.join();
    t2.join();
    return 0;
}

我的问题是,如何使用条件变量来实现这一点,并且可能使它更优雅一点?

1 个答案:

答案 0 :(得分:0)

您的代码中没有任何共享。每个线程都有一个局部变量i。 POSIX条件用于线程间通信/信令。这个想法很简单:

  1. 线程检查布尔谓词(取决于共享状态)并在谓词为假时决定“等待”(POSIX中的pthread_cond_wait)

  2. 另一个线程可以修改共享状态,从而影响布尔谓词的值。如果此线程更改状态,它可以通知另一个线程(线程#1)它应该被唤醒并重新检查其值可能已经更改的谓词(POSIX中的pthread_cond_signal和pthread_cond_broadcast)。

  3. 由于存在共享状态,因此需要一个互斥锁来保护该共享状态,并在修改或访问它时“锁定它”。

    POSIX条件的典型用例是共享队列。消费者希望从队列中“使用”数据项,并且为此必须等待布尔谓词[队列非空]。生产者生成它存放在共享队列中的数据项。当它添加项目时,它应该通知任何“服务员”他们应该重新检查。

    底线:条件在这里没有帮助。在您的示例中,您甚至不需要互斥锁。并且条件必须与互斥量一起使用(对pthread_cond_wait的调用将互斥体的地址作为输入,以原子方式释放锁并在条件下休眠)。互斥是用于互斥。条件适用于信令。两个非常不同的目的。