临界资源
临界区
每个线程 中 访问(操作)临界资源 的 那段代码 称为临界区(Critical Section),我们 每次 只准许 一个线程 进入 临界区
uint32_t value=0; **// 临界资源**
**/******** 这两个线程都是在系统中调度运行的 ********/
/**
* 假设thread1中value的值自加到10000之后,系统开始运行thread2,那么这就和我们本身的设计意图有了偏差
*
* 所以对于对于thread1 和 thread2中访问value的值的** **那段代码 我们需要 分别保护起来
*/**
void thread1_entry(void * para)
{
uint32_t i=0;
for(i=0;i<10000;i++)
{
rt_kprintf(“%d \\r\\n”,value);
value++; **// 设计意图:先把临界资源的值从0打印到10000**
}
}
void thread2_entry(void * para)
{
rt_thread_delay(50);
value=500; **// 设计意图:然后再把临界资源的值赋值成500**
}
临界区保护
第一种:禁止调度
禁止调度,即是把调度器锁住,不让其进行线程切换。这样就能保证当前运行的任务不被换出,直到调度器解锁,所以禁止调度是常用的临界区保护方法。
void thread_entry(void* parameter)
{
while(1)
{
**/* 调度器上锁 */** // 上锁后将不再切换到其他线程,仅响应中断
rt_enter_critical();
/* 以下进入临界区,进行临界资源的访问 */
. . . .
**/* 调度器解锁 */**
rt_exit_critical();
}
}
第二种:关闭中断
因为所有线程的调度都是建立在中断的基础上的,所以,当我们关闭中断后,系统将不能再进行调度,线程自身也自然不会被其他线程抢占了。
void thread_entry(void* parameter)
{
rt_base_t level;
while(1)
{
**/* 关闭中断*/**
level = rt_hw_interrupt_disable();
/* 以下进入临界区,进行临界资源的访问 */
. . . .
**/* 关闭中断*/**
rt_hw_interrupt_enable(level);
}
}