1. 任务创建与删除开销分析
任务说明
本案例目标是在 VxWorks 环境中测量任务创建(taskSpawn)与删除(taskDelete)的时间开销,并分析影响开销的关键因素。测量结果用于指导实时系统设计中的任务生命周期管理策略。
环境依赖
- VxWorks 6.9+ 或 7.x 开发环境
- 目标机或风河模拟器(VxSim)
- 包含
timestamp高精度计时驱动(或使用clock_gettime替代)
实现思路
使用系统高精度时间戳在任务创建前后分别取点,计算差值;删除操作在任务自身中执行,同样记录时间戳。为消除单次测量抖动,循环执行多次并统计平均值与最大值。关键分析维度包括:任务栈大小、任务优先级、系统当前任务数对创建/删除开销的影响。
关键完整代码
/* task_overhead.c - 任务创建与删除开销测量 */
#include <vxWorks.h>
#include <taskLib.h>
#include <timers.h>
#include <stdio.h>
#define MAX_ITER 1000
#define STACK_SIZE 8192
static UINT64 taskStartTime;
static UINT64 taskEndTime;
static UINT64 createTotal = 0;
static UINT64 deleteTotal = 0;
static UINT64 createMax = 0;
static UINT64 deleteMax = 0;
static int iterCount = 0;
/* 获取纳秒级时间戳 */
static UINT64 getNanoTime(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (UINT64)ts.tv_sec * 1000000000ULL + ts.tv_nsec;
}
/* 被创建的任务:记录删除时间并自杀 */
static void workerTask(void)
{
taskEndTime = getNanoTime();
taskDelete(0); /* 删除自身 */
}
/* 执行一轮创建+删除测量 */
static void measureOnce(int prio, int stackSize)
{
UINT64 t0, t1, createCost, deleteCost;
int tid;
t0 = getNanoTime();
tid = taskSpawn("tWorker", prio, 0, stackSize,
(FUNCPTR)workerTask, 0,0,0,0,0,0,0,0,0);
t1 = getNanoTime();
if (tid == ERROR) {
printf("taskSpawn failed\n");
return;
}
createCost = t1 - t0;
/* 等待任务完成删除 */
while (taskIdVerify(tid) == OK) {
taskDelay(1);
}
deleteCost = taskEndTime - taskStartTime;
createTotal += createCost;
deleteTotal += deleteCost;
if (createCost > createMax) createMax = createCost;
if (deleteCost > deleteMax) deleteMax = deleteCost;
iterCount++;
}
/* 测量入口 */
void measureTaskOverhead(void)
{
int i;
int prio = 100;
int stack = STACK_SIZE;
printf("=== Task Create/Delete Overhead (ns) ===\n");
/* 场景1:默认优先级与栈大小 */
iterCount = 0;
createTotal = deleteTotal = 0;
createMax = deleteMax = 0;
for (i = 0; i < MAX_ITER; i++) {
taskStartTime = getNanoTime();
measureOnce(prio, stack);
}
printf("Default prio=%d stack=%d\n", prio, stack);
printf(" Create avg=%llu max=%llu\n",
createTotal / iterCount, createMax);
printf(" Delete avg=%llu max=%llu\n",
deleteTotal / iterCount, deleteMax);
/* 场景2:高优先级 */
iterCount = 0;
createTotal = deleteTotal = 0;
createMax = deleteMax = 0;
for (i = 0; i < MAX_ITER; i++) {
taskStartTime = getNanoTime();
measureOnce(50, stack);
}
printf("High prio=%d stack=%d\n", 50, stack);
printf(" Create avg=%llu max=%llu\n",
createTotal / iterCount, createMax);
printf(" Delete avg=%llu max=%llu\n",
deleteTotal / iterCount, deleteMax);
/* 场景3:大栈 */
iterCount = 0;
createTotal = deleteTotal = 0;
createMax = deleteMax = 0;
for (i = 0; i < MAX_ITER; i++) {
taskStartTime = getNanoTime();
measureOnce(prio, 65536);
}
printf("Large stack prio=%d stack=65536\n", prio);
printf(" Create avg=%llu max=%llu\n",
createTotal / iterCount, createMax);
printf(" Delete avg=%llu max=%llu\n",
deleteTotal / iterCount, deleteMax);
}
编译与运行
# 在 VxWorks 开发环境中编译(以命令行为例)
ccpentium -c task_overhead.c -o task_overhead.o
# 链接到 VxWorks 镜像或作为动态加载模块
# 在目标机 shell 中运行
-> measureTaskOverhead
验证方法
- 程序正常输出三组场景的创建/删除平均耗时与最大耗时,数值单位为纳秒。
- 观察输出中高优先级任务(50)与默认优先级(100)的创建耗时差异,通常高优先级创建略慢(内核需插入更高优先级就绪队列)。
- 大栈(65536)场景的创建耗时应明显高于小栈(8192),反映内存分配与初始化成本。
- 删除耗时通常小于创建耗时,且受栈大小影响较小——删除主要释放 TCB 与内核资源,栈释放为整体操作。
预期输出示例
=== Task Create/Delete Overhead (ns) ===
Default prio=100 stack=8192
Create avg=4520 max=7830
Delete avg=3180 max=5420
High prio=50 stack=8192
Create avg=4890 max=8210
Delete avg=3220 max=5610
Large stack prio=100 stack=65536
Create avg=12450 max=18900
Delete avg=3350 max=5780
以上数值仅为逻辑一致的示例,实际数值取决于目标机 CPU 频率、内存速度与 VxWorks 内核配置。
关键因素分析
- 栈大小:创建时需分配并可能清零栈内存,是创建开销的主要变量。
- 优先级:影响就绪队列插入操作,高优先级插入可能触发更复杂的调度器路径。
- 系统负载:当前活动任务数影响内核链表操作与缓存命中率。
- 删除操作:主要固定成本在 TCB 释放与资源回收,与栈大小弱相关。