Contiki - PROCESS_WAIT_EVENT_UNTIL
Contiki - PROCESS_WAIT_EVENT_UNTIL
PROCESS_WAIT_EVENT_UNTIL(c) 是 Contiki 操作系统中用于 进程 (Process) 的一个宏,定义在 sys/process.h 头文件中。
1. 功能
这个宏结合了两种操作:
等待事件: 它使当前进程挂起,直到接收到一个事件(与 PROCESS_WAIT_EVENT() 类似)。
条件判断: 在接收到事件后,它会检查一个布尔条件 c。只有当条件 c 为真时,进程才会从 PROCESS_WAIT_EVENT_UNTIL 宏处恢复并继续执行。如果条件 c 为假,进程会再次挂起并等待下一个事件。
2. 工作原理
1)首次检查: 当进程执行到 PROCESS_WAIT_EVENT_UNTIL(condition) 时,首先会检查 condition 是否为真。如果为真,则宏立即返回,代码继续执行,无需挂起。
2)挂起与等待: 如果 condition 为假,进程会被置于“等待事件”状态,并从可运行队列中移除。
3)事件到达: 当进程接收到一个事件时(无论该事件是否与条件 c 直接相关),它会被唤醒。
4)评估条件: 进程恢复后,会立即重新评估 condition 表达式。
5)继续或再次等待:
如果此时 condition 为真,宏返回,代码继续执行。
如果 condition 仍然为假,进程会再次调用底层的等待机制,挂起并等待下一个事件。
6)获取事件: 与 PROCESS_WAIT_EVENT 一样,当进程因事件被唤醒并最终满足条件后,唤醒它的那个事件的类型会被存储在 process_event 变量中,事件数据存储在 process_data 中。
3. 使用场景
当你需要等待一个特定的事件并且这个事件的发生还需要满足某个额外的条件时,PROCESS_WAIT_EVENT_UNTIL 非常有用。它避免了在一个简单的 while(!condition) { PROCESS_WAIT_EVENT(); } 循环中可能出现的竞态条件(race condition),因为事件可能在检查条件和调用 PROCESS_WAIT_EVENT 之间发生。
4. 示例
假设你想等待一个特定的自定义事件 my_custom_event,并且只有在某个全局标志 flag_is_set 为真时才处理它。
点击查看代码
#include "contiki.h"
#include <stdio.h>
// 假设定义了一个自定义事件
#define MY_CUSTOM_EVENT PROCESS_EVENT_MAX
static uint8_t flag_is_set = 0;
PROCESS(example_wait_until_process, "Wait Until Example");
AUTOSTART_PROCESSES(&example_wait_until_process);
// 假设有一个外部函数会在某个时刻触发事件和设置标志
extern void trigger_my_event(void);
PROCESS_THREAD(example_wait_until_process, ev, data) {
PROCESS_BEGIN();
printf("Process started, waiting for event with condition.\n");
// 等待 MY_CUSTOM_EVENT 事件,并且要求 flag_is_set 为 1
PROCESS_WAIT_EVENT_UNTIL(ev == MY_CUSTOM_EVENT && flag_is_set);
printf("Condition met! Event received and flag is set.\n");
PROCESS_END();
}
// 模拟外部触发器
void trigger_my_event(void) {
flag_is_set = 1; // 先设置标志
process_post(&example_wait_until_process, MY_CUSTOM_EVENT, NULL); // 再发送事件
}
在这个例子中,进程会等待 MY_CUSTOM_EVENT 事件。但是,只有当 flag_is_set 也为真时,进程才会从 PROCESS_WAIT_EVENT_UNTIL 恢复。如果事件先到达但标志未设置,进程会继续等待下一个事件,并在每次唤醒时重新检查条件。这确保了进程只在满足所有条件时才继续执行。
如有侵权请联系删除

浙公网安备 33010602011771号