QWaitCondition

来源:互联网 发布:灿妞儿 知乎 编辑:程序博客网 时间:2024/05/18 06:19

QWaitCondition提供一个条件变量来实现线程间同步。

QWaitConditions允许一个线程告诉其它线程某种条件已经满足,一个或多个线程可以等待一个由wakeOne()wakeAll()设定的条件QWaitCondition。使用wakeOne()会唤醒一种随机选择的事件或者wakeAll()会把它们全部唤醒。

比如,假定每次用户按下一个键,我们有三个任务要同时执行,每个任务都可以放到一个线程中,每个线程的run()都应该是这样:

forever {

     mutex.lock();

     keyPressed.wait(&mutex);

     do_something();

     mutex.unlock();

 }

这里,,keyPressed变量是个全局的QWaitCondition.类型变量。

第四个线程应该读按键,每当它收到一个按键就唤醒其他三个线程,它应该像这样:

forever {

     getchar();

     keyPressed.wakeAll();

 }

注意这三个线程被唤醒的顺序是未定义的,并且当键被按下时,这些线程中的一个或多个还在do_something(),它们将不会被唤醒(因为它们现在没有等待条件变量)并且这个任务也就不会针对这次按键执行操作。这种情况是可以通过使用一个计数器和互斥量来避免,比如,修改后的线程代码如下

forever {

     mutex.lock();

     keyPressed.wait(&mutex);

     ++count;

     mutex.unlock();

     do_something();

     mutex.lock();

     --count;

     mutex.unlock();

 }

这是第四个线程的代码:

forever {

     getchar();

     mutex.lock();

     // Sleep until there are no busy worker threads

     while (count > 0) {

         mutex.unlock();

         sleep(1);

         mutex.lock();

     }

     keyPressed.wakeAll();

     mutex.unlock();

 }

互斥量是必须的,因为两个线程试图同时对同一个变量进行修改的结果是不可预知的。

等待条件是一个有用的线程同步方法。等待条件的例子展示了如何运用QWaitCondition代替QSemaphore来实现操作环形缓冲区。消费者和生产者共享环形缓冲区。

请参考 QMutex, QSemaphore, QThread, and Wait Conditions Example.

成员函数说明

QWaitCondition::QWaitCondition ()

创建一个新的等待条件对象

QWaitCondition::~QWaitCondition ()

销毁一个等待条件对象

bool QWaitCondition::wait ( QMutex * mutex, unsigned long time = ULONG_MAX )

释放锁定的mutex并且在线程事件对象上等待。mutex必须由调用线程初始锁定的。如果mutex没有在锁定状态,这个函数立即返回。如果mutex是一个递归互斥量,这个函数立即返回。mutex将被解锁,并且调用线程将会阻塞,直到下列条件之一满足时才醒来:

   另一个线程使用wakeOne()wakeAll()传输信号给它。在这种情况下,函数将返回真。

   time毫秒过去了。如果timeULONG_MAX(默认值),那么这个等待将永远不会超时(这个事件必须被传输)。如果等待的事件超时,这个函数将会返回假。

互斥量将以同样的锁定状态返回。这个函数提供的是允许从锁定状态到等待状态的原子转换。

请参考 wakeOne() and wakeAll().

bool QWaitCondition::wait ( QReadWriteLock * readWriteLock, unsigned long time = ULONG_MAX )

释放锁定的readWriteLock并且在线程事件对象上等待。readWriteLock必须由调用线程初始锁定的。如果readWriteLock没有在锁定状态,这个函数立即返回。如果readWriteLock是一个递归互斥量,这个函数立即返回。readWriteLock将被解锁,并且调用线程将会阻塞,直到下列条件之一满足时才醒来:

另一个线程使用wakeOne()wakeAll()传输信号给它。在这种情况下,这个函数将返回真。

time毫秒过去了。如果timeULONG_MAX(默认值),那么这个等待将永远不会超时(这个事件必须被传输)。如果等待的事件超时,这个函数将会返回假。

互斥量将以同样的锁定状态返回。这个函数提供的是允许从锁定状态到等待状态的原子转换。

Qt 4.4 引进了该函数

请参考 wakeOne() and wakeAll().

void QWaitCondition::wakeAll ()

这将会唤醒所有等待QWaitCondition的线程。这些线程被唤醒的顺序依赖于操组系统的调度策略,并且不能被控制或预知。

请参考 wakeOne().

void QWaitCondition::wakeOne ()

这将唤醒某个等待QWaitCondition的线程。具体是那个线程被唤醒取决于操作系统的调度策略,并且不能被控制或预知。

如果想唤醒某个指定的线程,一般的办法是定义不同的等待条件QWaitCondition,让不同的线程等待不同的等待条件。

请参考 wakeAll()