条件变量使线程能够等待,直到发生特定条件。

概念

可以定义任意数量的条件变量(仅受可用 RAM 的限制)。每个条件变量都由其内存地址引用。
等待条件变为真,线程可以使用条件变量。
条件变量基本上是一个线程队列,当某些执行状态不符合预期时,线程会阻塞。函数k_condvar_wait()以原子方式执行以下步骤:

  • 释放上次获取的互斥锁。
  • 将当前线程放在条件变量队列中。

当条件变量状态改变时,可以唤醒一个或多个等待线程。
当阻塞线程获取到k_condvar_signal()k_condvar_broadcast()发出的条件信号时,它执行如下步骤:

  • 重新获取先前发布的互斥锁。
  • k_condvar_wait() 返回。

必须先初始化条件变量,然后才能使用它。

定义条件变量

条件变量是使用k_condvar类型定义的变量。然后必须通过调用k_condvar_init()对其进行初始化。

  1. struct k_condvar my_condvar;
  2. k_condvar_init(&my_condvar);

也可以通过调用K_CONDVAR_DEFINE在编译时定义和初始化条件变量。

  1. K_CONDVAR_DEFINE(my_condvar);

等待条件变量

线程可以通过调用k_condvar_wait()来等待条件。

  1. K_MUTEX_DEFINE(mutex);
  2. K_CONDVAR_DEFINE(condvar)
  3. void main(void)
  4. {
  5. k_mutex_lock(&mutex, K_FOREVER);
  6. /* block this thread until another thread signals cond. While
  7. * blocked, the mutex is released, then re-acquired before this
  8. * thread is woken up and the call returns.
  9. */
  10. k_condvar_wait(&condvar, &mutex, K_FOREVER);
  11. ...
  12. k_mutex_unlock(&mutex);
  13. }

向条件变量发出信号

通过为一个线程调用k_condvar_signal() 或通过对多个线程调用k_condvar_broadcast()来发出条件变量的信号。

  1. void worker_thread(void)
  2. {
  3. k_mutex_lock(&mutex, K_FOREVER);
  4. /*
  5. * Do some work and fulfill the condition
  6. */
  7. ...
  8. ...
  9. k_condvar_signal(&condvar);
  10. k_mutex_unlock(&mutex);
  11. }

条件变量与互斥锁

条件变量互斥锁一起使用,以指示从一个线程到另一个线程的状态变化。条件变量不是条件本身,也不是事件。
互斥锁本身不是为用作通知/同步机制而设计的。它们旨提供对共享资源的互斥访问。