天天看点

OpenThreads库介绍——Condition

1. 简介

Condition 类是条件变量。它依赖于某个Mutex 互斥体,互斥体加锁时阻塞所在的线程,解锁或者超过时限则释放此线程,允许其继续运行。这里涉及了几个线程操作中重要的概念:同步,阻塞以及条件变量。线程同步,简单来说就是使同一进程的多个线程可以协调工作,例如让它们都在指定的执行点等待对方,直到全员到期之后才开始同步运行;拥塞,即强制一个线程在某个执行点上等待,直到满足继续运行的条件为止。例如其它的线程到达同一执行点,某个变量初始化完成等等,可以通过条件变量来设计各种条件。

条件变量有点类似于一种事件,用来通知两个或者更多线程。可以让一个或者多个线程等待条件变量的通知,另一个线程可以触发这些通知。

关于条件变量的使用场景可以参考条件变量(Condition Variable)详解

2. 使用方式

OSG里面的条件变量提供的接口非常少,下面一一列举:

  • wait(Mutex *mutex)

    用来获取一个Mutex,并且判断当前条件是否满足,如果条件不满足,那么进入到阻塞状态,并且释放这个Mutex

  • wait(Mutex *mutex, unsigned long int ms)

    获取一个Mutex,等待ms的时间

  • signal

    其他线程的线程通过调用这个函数来唤醒阻塞的一个线程

  • broadcast

    其他线程通过调用这个函数来唤醒所有被阻塞的线程

关于条件变量的使用方式,可以参考《用条件变量实现事件等待器的正确与错误做法》

3.示例程序

#include "header.h"
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
#include <iostream>


OpenThreads::Mutex g_mutex;
OpenThreads::Condition g_condition;
bool ready = false;

//WorkThread是被阻塞,等待唤醒的线程
class WorkThread : public OpenThreads::Thread
{
public:
    WorkThread(){ }

    void run()
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> mutex(g_mutex);
        while (!ready)
        {
            g_condition.wait(&g_mutex);
        }
        std::cout << "Work Thread Wake up and coming" << std::endl;
    }
};

//NodifyThread是唤醒被阻塞线程的线程
class NotifyThread : public OpenThreads::Thread
{
public:
    NotifyThread(){}

    void run()
    {
        std::cout << "Start Notify Thread" << std::endl;
        OpenThreads::ScopedLock<OpenThreads::Mutex> mutex(g_mutex);
        ready = true;
        std::cout << "Work Thread Go!" << std::endl;
        g_condition.signal();

    }
};


int main()
{
    WorkThread w;
    NotifyThread n;
    w.start();
    n.start();
    w.join();
    n.join();
           

4. 参考资料

1. std::condition_variable

2. 条件变量(Condition Variable)详解

3. 用条件变量实现事件等待器的正确与错误做法

继续阅读