C8、 用户方式的线程同步

本文介绍Windows环境下互锁函数的应用及关键代码段(临界区)的管理技巧,包括互锁函数的原子操作特性及其多种实现方式,以及如何通过CRITICAL_SECTION结构来有效管理和保护共享资源。

(用户方式同步的优点:同步速度快;但是,锁函数缺点:单值,不能使线程进入等待状态;关键代码段:单进程中的线程实施同步,易死锁)

 

一、互锁函数(原子方式运行,速度快!):

a)         LONG InterLockedExchangeAdd(PLONG plAdded, LONG lIncrement);

//相当于*plAdded += lIncrement;

b)        LONG InterLockedExchange(PLONG plTarget, LONG lValue);

//相当于* plTarget = lValue;

c)        PVOID InterLockedExchangePointer(PVOID* ppvTarget, PVOID pvValue); //同上

d)        PVOID InterLockedCompareExchange (PLONG plDestinationLONG lExchange, LONG lCompared);

//相当于if(*plDestination == lCompared) *plDestination = lExchange;

e)         PVOID InterLockedCompareExchange Pointer(PVOID* ppvDestinationPVOID pvExchange,  PVOID pvCompared);

f)         老函数:

LONG InterlockedIncrement(PLONG plAdded);

LONG InterlockedDecrement(PLONG plAdded);

二、关键代码段(临界段)

a)         CRITICAL_SECTION结构变量;

b)        在任何需要访问公共资源处,封装在函数对中:EnterCriticalSectionLeaveCriticalSection

c)        如果有多个不是一道使用的资源,为每个资源设立CRITICAL_SECTION变量。如果同时访问这多个资源,分别使用EnterCriticalSectionLeaveCriticalSection,并且按照完全相同的顺序请求访问。不要长时间运行关键代码段,如不能避免,可用临时变量。

d)        如果动态创建CRITICAL_SECTION结构,使用前需初始化(VOID InitializeCriticalSection(pcs);,用完后需释放(VOID DeleteCriticalSection(pcs);

e)         如果不允许调用线程进入等待状态,可以用:BOOL TryEnterCriticalSectionpcs;

如果返回FALSE(不能访问),则转到执行其他操作(而EnterCriticalSection将进入等待)。

f)         使用循环锁(避免线程转入内核方式而降低性能)。

                         i.              需先初始化:BOOL InitializeCriticalSectionAndSpinCountpcs dwSpinCount);dwSpinCount为循环次数(4000?)(单处理器无效);

                       ii.              改变循环次数:DWORD SetCriticalSectionSpinCount(pcs, dwSpinCount);

g)        异常:可能失败调用InitializeCriticalSection,用InitializeCriticalSectionAndSpinCount较易跟踪。如果在内存短缺的环境,需预先分配事件内核对象,避免EnterCriticalSection产生EXCEPTION_INVALID_HANDLE

### STM32F103C8T6 多线程编程方法 STM32F103C8T6 是一款基于 ARM Cortex-M3 架构的微控制器,虽然该架构本身不提供操作系统级别的多线程支持,但可以通过引入实时操作系统 (RTOS) 来实现高效的多线程管理。常见的 RTOS 如 FreeRTOS 和 CMSIS-RTOS 可用于此平台。 #### 选择合适的 RTOS 平台 FreeRTOS 是一种轻量级的操作系统内核,专为嵌入式设备设计,特别适合资源有限的小型系统。它提供了任务调度、同步机制等功能来简化并发处理[^1]。 CMSIS-RTOS 是由 Arm 提供的标准 API 接口集合,允许不同厂商提供的 RTOS 内核之间互操作。对于 STM32 用户来说,使用 ST 自带的支持包可以更方便地集成 CMSIS-RTOS 功能。 #### 初始化 RTOS 环境 无论是选用 FreeRTOS 还是 CMSIS-RTOS,在项目初始化阶段都需要完成必要的配置工作: ```c // 导入头文件 #include "cmsis_os.h" osThreadId_t threadHandle_1; osThreadId_t threadHandle_2; void ThreadFunction(void *argument); int main(void){ // ...省略其他初始化代码... osKernelInitialize(); /* Initialize the kernel */ // 创建两个线程实例 const osThreadAttr_t attr = { .name = "TaskName", .priority = (osPriority_t)(osPriorityNormal), .stack_size = 128 * 4, }; threadHandle_1 = osThreadNew(ThreadFunction, NULL, &attr); threadHandle_2 = osThreadNew(ThreadFunction, NULL, &attr); osKernelStart(); } ``` 上述代码展示了如何创建并启动多个线程。`osThreadNew()` 函数用来新建一个线程对象,并指定其入口函数 `ThreadFunction`;最后调用 `osKernelStart()` 启动整个系统的调度循环。 #### 编写线程体函数 每个线程都有自己的执行流程,通常定义在一个独立的任务函数里: ```c void ThreadFunction(void *argument){ while(1){ // 执行具体业务逻辑... osDelay(500); /* Delay for a specified number of ticks */ } } ``` 这里展示了一个简单的无限循环结构作为线程主体部分,其中包含了延时等待语句 `osDelay()`, 使得当前线程不会占用过多 CPU 时间片。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值