Skip to content

条件变量

async_simple中实现的条件变量类似于C++标准库中std::condition_variable。主要区别在于async_simple中条件变量面向Lazy协程。协程阻塞在条件变量上时,不会阻塞住当前线程。用于多个协程之间交互协作。基于协程版条件变量,多个协程可以实现典型生产者消费者模型。

用法

ConditionVariable

  • 条件变量需要配合一个互斥锁来使用。互斥锁用于保证更改条件和查询条件这些操作原子性。可以用任意一种带有coLock()/unlock()方法的互斥锁配合条件变量使用。下面展示了用自旋锁配合条件变量用法。
cpp
#include <async_simple/coro/ConditionVariable.h>

using namespace async_simple::coro;

SpinLock mtx;
ConditionVariable<SpinLock> cond;
int value = 0;

Lazy<> producer() {
  co_await mtx.coLock();
  value++;
  cond.notify();
  mtx.unlock();
  co_return;
}

Lazy<> consumer() {
  co_await mtx.coLock();
  co_await cond.wait(mtx, [&] { return value > 0; });
  mtx.unlock();
  assert(value > 0);
  co_return;
}
  • 注意:与std::condition_vaiable不同的是,ConditionVariable<Lock>是一个模板类,wait的参数是Lock而非std::unique_lock<std::mutex>,我们也提供了notifyAllnofifyOne接口,notifynotifyAll语义相同。

Notifier

  • 当条件变量中条件只是true/false这种情况时,条件变量可以退化为Notifier。Notifier不依赖外部互斥锁。
cpp
#include <async_simple/coro/ConditionVariable.h>

using namespace async_simple::coro;

Notifier notifier;
bool ready = false;

Lazy<> producer() {
  ready = true;
  notifier.notify();
  co_return;
}

Lazy<> consumer() {
  co_await notifier.wait();
  assert(ready);
  co_return;
}

不论条件变量还是Notifier都允许多个协程同时wait在上面。一旦notify()被调用,所有之前阻塞住的协程都将依次被唤醒执行。

避免内存泄漏

当一个协程 co_await condition_variable::wait(...); 时,程序员需要保证当前协程在程序执行期间会被唤醒,否则程序可能会出现内存泄漏问题。

This website is released under the MIT License.