1.4.12 线程本地存储
优质
小牛编辑
135浏览
2023-12-01
线程本地存储指针允许开发者存储值到任务的控制块(control block)中,使这个值对于任务来说是特定且唯一的。
线程本地存储经常被用来存储数据,而单一进程的应用程序通常的做法是使用全局变量。比如,很多库函数包含一个全局的返回值--错误信息,应用根据这个错误信息判读错误类型,同时进行相应处理。在单线程的应用中可以使用全局变量来保存这个错误信息,但是在多任务的系统中,每个任务都必须有一个自己的位置去存储这个错误信息,否则的话,会导致一个任务读取到另外一个任务的错误信息的混乱情况。
freeRTOS提供给开发者一个很灵活的实现线程本地存储的机制---使用线程本地存储指针。
configNUM_THREAD_LOCAL_STORAGE_POINTERS
配置任务数组大小(以void *
的大小为单位)。vTaskSetThreadLocalStoragePointer()
写入数据到线程的本地存储,pvTaskGetThreadLocalStoragePointer()
读取线程本地存储的数据。示例如下:
大小小于等于空类型的指针(void *
)的大小的变量可以直接存在线程本地存储指针指向的数组。如果sizeof( void * )
等于4个字节,那么32-bit的数可以直接存入。
uint32_t ulVariable;
/* 写 32-bit 的数据 0x12345678 到线程本地存储数组的索引1的
位置上,NULL,代表写入当前调用的任务的本地存储*/
vTaskSetThreadLocalStoragePointer( NULL, /* 任务句柄. */ 1, /* 数组索引 */ ( void * ) 0x12345678 );
ulVariable = ERROR_CODE;
vTaskSetThreadLocalStoragePointer( NULL, /* 任务句柄 */ 0, /* 数组索引*/ ( void * ) ulVariable );
/* 读取索引5的数据. */
ulVariable = ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );
上面的例子演示了如何存取一个数值,下面的例子演示了如何存取结构体的指针:
typedef struct
{uint32_t ulValue1;uint32_t ulValue2;
} xExampleStruct;
xExampleStruct *pxStruct;
/* 创建这个任务使用的结构体 */
pxStruct = pvPortMalloc( sizeof( xExampleStruct ) );
/* 设置结构体成员 */
pxStruct->ulValue1 = 0;
pxStruct->ulValue2 = 1;
/* 保存结构体指针到数组的索引0处 */
vTaskSetThreadLocalStoragePointer( NULL, /* Task handle. */ 0, /* Index into the array. */ ( void * ) pxStruct );
/* 读取保存在线程本地存储的指针 */
pxStruct = ( xExampleStruct * ) pvTaskGetThreadLocalStoragePointer( NULL, 0 );