RT_Thread_临界资源保护

本文介绍了临界资源和临界区的概念,它们是指在同一时刻仅允许一个线程访问的资源和代码段。临界区的保护通常涉及关闭系统调度、禁止中断以及使用信号量和互斥量等机制。通过rt_hw_interrupt_disable/enable关闭中断,rt_enter/exit_critical禁用调度,或者使用rt_sem和rt_mutex实现线程间的互斥访问,确保了资源的安全访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、临界资源、临界区

1.1、临界资源

任何时刻最多只允许一个线程去使用的资源。

进程间要以互斥的方式访问临界资源。

属于临界资源的硬件:打印机、音响、屏幕等;软件:消息队列,变量,数组,缓冲区等。

1.2、临界区

每个进程中访问临界资源的那段代码称为临界区(criticalsection)。

多个进程涉及到同一个临界资源的的临界区称为相关临界区。

使用临界区时,一般不允许其运行时间过长,只要运行在临界区的线程还没有离开,其他所有进入此临界区的线程都会被挂起而进入等待状态,并在一定程度上影响程序的运行性能。

2、如何保护临界区

2.1、关闭系统调度

  • 禁止中断
rt_base_t level;
level = rt_hw_interrupt_disable();
//......
rt_hw_interrupt_enable(level);
  • 关闭调度(还可响应中断)
rt_enter_critical();    //不再切换其他线程,但可以响应中断
//......
rt_exit_critical();

2.2、利用互斥

  • 信号量

  二值信号量,即信号量的初始值为1,访问临界区时-1,访问完释放+1;

//初始化信号量
rt_sem_init(&sem_lock, "lock", 1 ,RT_IPC_FLAG_PRIO);
//访问临界资源时,上锁
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
//......
//访问完,解锁
rt_sem_release(&sem_lock);

 

  • 互斥量
/* 指向互斥量的指针 */
static rt_mutex_t dynamic_mutex = RT_NULL;
/* 创建一个动态互斥量 */
dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_PRIO);
if (dynamic_mutex == RT_NULL)
{
    rt_kprintf("create dynamic mutex failed.\n");
    return -1;
}
//开始访问临界资源
rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
//......
//结束访问临界资源
rt_mutex_release(dynamic_mutex);
### RT-Thread 操作系统中的锁机制 在RT-Thread操作系统中,锁是一种重要的同步原语,用于保护共享资源不被多个线程同时访问。这有助于防止数据竞争和其他并发问题的发生。 #### 互斥量 (Mutex) 互斥量是实现锁定功能的一种方式,在多线程环境中用来确保同一时间只有一个线程可以访问特定的临界区。创建并初始化一个互斥量可以通过`rt_mutex_create()`函数完成[^3]: ```c rt_err_t rt_mutex_create(rt_mutex_t *mutex, const char *name); ``` 当某个线程希望进入临界区时,则需调用`rt_mutex_take()`来尝试获取该互斥量;而离开临界区之前要记得释放它——即通过`rt_mutex_release()`把控制权交还给其他等待中的线程[^3]: ```c // 尝试获得互斥量 rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time); // 释放已持有的互斥量 rt_err_t rt_mutex_release(rt_mutex_t mutex); ``` #### 自旋锁 (Spinlock) 自旋锁适用于短时间段内的独占性访问需求场景下工作良好。如果当前持有者很快就能结束其操作的话,那么后续请求者将会持续循环检查直到前一位使用者完全退出为止。定义和使用自旋锁如下所示[^4]: ```c /* 定义静态自旋锁 */ static struct rt_spinlock spin; /* 初始化自旋锁 */ void init_spinlock(void){ rt_hw_spin_lock_init(&spin); } /* 获取自旋锁 */ void take_spinlock(void){ rt_hw_spin_lock(&spin); } /* 释放自旋锁 */ void release_spinlock(void){ rt_hw_spin_unlock(&spin); } ``` #### 信号量(Semaphore) 除了上述两种类型的锁外,RT-Thread 还提供了二值信号量作为另一种形式的同步工具。它可以看作是一个计数器加条件变量组合而成的对象,允许设定最大数量限制以及支持阻塞式挂起/唤醒机制。下面给出了一段简单的例子说明如何利用此类对象来进行进程间通信[^5]: ```c #include <rtthread.h> #define SEM_COUNT 10 /* 设置信号量初始值 */ static struct rt_semaphore sem; int count = 0; /* 创建具有指定初值的信号量实例 */ rt_sem_init(&sem,"my_semaphore",SEM_COUNT,RT_IPC_FLAG_FIFO); /* 减少信号量计数值 */ if (rt_sem_trytake(&sem)==RT_EOK){ // 成功减少了一个单位... }else{ // 失败处理逻辑... } /* 增加信号量计数值 */ rt_sem_release(&sem); ``` 以上就是有关于RT-Thread 中几种常见锁机制及其基本应用介绍。每种类型都有各自特点及适用范围,请根据实际项目情况合理选用合适的方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值