概念
可以定义任意数量的信号量(仅受可用 RAM 的限制)。每个信号量都由其内存地址引用。
信号量具有以下关键属性:
- 指示可以获取信号量的次数的计数。计数为零表示信号量不可用。
- 指示信号量计数可以达到的最大值的限制。
必须先初始化信号量,然后才能使用它。其计数必须设置为小于或等于其限制的非负值。
信号量可以由线程或 ISR 给出。提供信号量会增加其计数,除非计数已等于限制。
信号量可以由线程获取。获取信号量会减少其计数,除非信号量不可用(即在零处)。当信号量不可用时,线程可以选择阻塞等待。任意数量的线程可以同时等待不可用的信号量。给出信号量时,它由等待时间最长的优先级最高的线程获取。
定义信号量
信号量是使用k_sem
类型定义的变量。然后必须通过调用k_sem_init()
对其进行初始化。
下面的代码定义一个信号量,然后通过将其计数设置为 0 并将其限制设置为 1 来将其配置为二进制信号量。
struct k_sem my_sem;
k_sem_init(&my_sem, 0, 1);
也可以通过调用K_SEM_DEFINE
在编译时定义和初始化信号量。
K_SEM_DEFINE(my_sem, 0, 1);
释放信号量
信号量是通过调用k_sem_give()
释放信号量。
void input_data_interrupt_handler(void *arg)
{
/* notify thread that data is available */
k_sem_give(&my_sem);
...
}
获取信号量
信号量是通过调用k_sem_take()
来获取。
void consumer_thread(void)
{
...
if (k_sem_take(&my_sem, K_MSEC(50)) != 0) {
printk("Input data not available!");
} else {
/* fetch available data */
...
}
...
}