4. 信号量获取释放延迟优化
任务目标
在VxWorks实时系统中,信号量获取/释放延迟直接影响任务响应时间。本案例完成两件事:测量二进制信号量与互斥信号量的获取释放延迟(使用clock_gettime获取纳秒级时间戳),并通过缩小临界区范围优化延迟。
环境依赖
- VxWorks 7或6.9+,支持POSIX时钟接口
- 包含
semLib.h、time.h、taskLib.h
关键完整代码
/* sem_latency_demo.c */
#include <vxWorks.h>
#include <semLib.h>
#include <time.h>
#include <taskLib.h>
#include <stdio.h>
#define ITERATIONS 1000
/* 模拟临界区工作负载:简单计算 */
static void do_work(int workload) {
volatile int sum = 0;
for (int i = 0; i < workload; i++) {
sum += i;
}
}
/* 获取纳秒时间戳 */
static UINT64 get_ns(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (UINT64)ts.tv_sec * 1000000000ULL + ts.tv_nsec;
}
/* 测量信号量获取/释放延迟 */
static void measure_sem(SEM_ID sem, const char *name, int workload) {
UINT64 start, end, total = 0;
int i;
for (i = 0; i < ITERATIONS; i++) {
start = get_ns();
semTake(sem, WAIT_FOREVER);
do_work(workload); /* 临界区内工作 */
semGive(sem);
end = get_ns();
total += (end - start);
}
printf("%s (workload=%d): avg latency = %llu ns\n",
name, workload, (unsigned long long)(total / ITERATIONS));
}
/* 优化前:临界区内包含不必要的工作 */
static void unoptimized(SEM_ID bin_sem, SEM_ID mutex_sem) {
measure_sem(bin_sem, "binary unoptimized", 100);
measure_sem(mutex_sem, "mutex unoptimized", 100);
}
/* 优化后:仅将必要共享资源保护在临界区内 */
static void optimized(SEM_ID bin_sem, SEM_ID mutex_sem) {
measure_sem(bin_sem, "binary optimized", 10);
measure_sem(mutex_sem, "mutex optimized", 10);
}
void sem_latency_demo(void) {
SEM_ID bin_sem, mutex_sem;
/* 创建信号量 */
bin_sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
mutex_sem = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
if (bin_sem == NULL || mutex_sem == NULL) {
printf("Semaphore creation failed\n");
return;
}
printf("--- Semaphore Latency Measurement ---\n");
unoptimized(bin_sem, mutex_sem);
optimized(bin_sem, mutex_sem);
/* 清理 */
semDelete(bin_sem);
semDelete(mutex_sem);
}
运行与验证
- 将代码编译链接到VxWorks镜像或作为可下载模块加载:
cc -c sem_latency_demo.c -o sem_latency_demo.o
ld -r sem_latency_demo.o -o sem_latency_demo.out - 在VxWorks shell中调用:
sem_latency_demo - 通过判定标准:程序正常输出4行延迟数据;优化后(workload=10)的平均延迟应明显低于优化前(workload=100)——因为临界区执行时间缩短,阻塞时间减少。若系统负载稳定,多次运行结果应具有可重复性。
关键说明
- 本案例通过缩小临界区内工作量(从100次循环降至10次)模拟优化,实际项目中应将非共享资源操作移出临界区。
- 互斥信号量启用
SEM_INVERSION_SAFE(优先级继承),在优先级反转场景下延迟特性与二进制信号量不同。 - 测量包含
semTake/semGive系统调用开销及任务调度时间,反映真实获取释放延迟。 - 若需更精确测量,可关闭中断或使用
taskLock,但会改变实时行为,本案例保持真实运行环境。