禁止系统调度
上一节《 多线程导致的临界区问题》中由于 test1 线程被 test2 线程打断,才导致了我们没有得到预期的结果,我们一般可通过关闭中断和调度器上锁这两种简单的途径来禁止系统调度,防止线程被打断,从而保证临界区不被破坏。

1、 关闭中断
线程中关闭中断保护临界区的结构如下:

#include <rtthread.h>
#include <stm32f10x.h>
#include "test.h" rt_uint32_t g_tmp;/* 定义一个全局变量*/ /* 变量分配4字节对齐 */
ALIGN(RT_ALIGN_SIZE) /* 静态线程的 线程堆栈*/
static rt_uint8_t thread1_stack[];
static rt_uint8_t thread2_stack[]; /* 静态线程的 线程控制块 */
static struct rt_thread thread_test1;
static struct rt_thread thread_test2; static void test1_thread_entry(void* parameter);
static void test2_thread_entry(void* parameter); void demo_thread_creat(void)
{
rt_err_t result; /* 创建静态线程 : 优先级 16 ,时间片 2个系统滴答 */
result = rt_thread_init(&thread_test1,
"test1",
test1_thread_entry, RT_NULL,
(rt_uint8_t*)&thread1_stack[], sizeof(thread1_stack), , ); if (result == RT_EOK)
{
rt_thread_startup(&thread_test1);
} /* 创建静态线程 : 优先级 15 ,时间片 1个系统滴答 */
result = rt_thread_init(&thread_test2,
"test2",
test2_thread_entry, RT_NULL,
(rt_uint8_t*)&thread2_stack[], sizeof(thread2_stack), , ); if (result == RT_EOK)
{
rt_thread_startup(&thread_test2);
} } void test1_thread_entry(void* parameter)
{
rt_uint32_t i; /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical(); g_tmp = ;
rt_kprintf("g_tmp=:%d \r\n", g_tmp);
for(i=; i<; i++)
{
g_tmp++;
}
rt_kprintf("g_tmp=:%d \r\n", g_tmp); /* 调度器解锁 */
rt_exit_critical();
} void test2_thread_entry(void* parameter)
{
rt_thread_delay();//
g_tmp++;
}

把调度器锁住也能让当前运行的任务不被换出,直到调度器解锁。但和关闭中断有一点不相同的是,对调度器上锁,系统依然能响应外部中断,中断服务例程依然有可能被运行。
所以在使用调度器上锁的方式来做任务同步时,需要考虑好, 任务访问的临界资源是否会被中断服务例程所修改,如果可能会被修改,那么将不适合采用此种方式作为同步的方法。

PS: 上面两种方法的的宗旨其实就是:在临界区内只允许一个线程运行!

除了禁止调度器调度,我们还用线程间通信的方式来保证线程间的同步, 下面我们来介绍 RT-Thread 中的 IPC 对象:信号量、互斥锁、事件、消息队列、邮箱。

RT-Thread的线程间同步的更多相关文章

  1. c++11 线程间同步---利用std::condition_variable实现

    1.前言 很多时候,我们在写程序的时候,多多少少会遇到下面种需求 一个产品的大致部分流程,由工厂生产,然后放入仓库,最后由销售员提单卖出去这样. 在实际中,仓库的容量的有限的,也就是说,工厂不能一直生 ...

  2. C#线程间同步无法关闭

    用C#做了个线程间同步的小程序,但每次关闭窗口后进程仍然在,是什么原因? 解决方法: 要加一句 线程.IsBackground = true; 否则退出的只是窗体 上面的方法没看懂... MSDN上说 ...

  3. Linux系统编程(29)——线程间同步(续篇)

    线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行.在pthread库中通过条件变 ...

  4. linux线程间同步方式汇总

    抽空做了下linux所有线程间同步方式的汇总(原生的),包含以下几个: 1, mutex 2, condition variable 3, reader-writer lock 4, spin loc ...

  5. conditon_variable(条件变量)用于线程间同步

    conditon_variable(条件变量)用于线程间同步 condition_variable有5个函数,函数名及对应的功能如下: wait阻塞自己,等待唤醒 wait_for阻塞自己,等待唤醒, ...

  6. rtt学习之线程间同步与通信

    一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...

  7. Linux进程间通信与线程间同步详解(全面详细)

    引用:http://community.csdn.net/Expert/TopicView3.asp?id=4374496linux下进程间通信的几种主要手段简介: 1. 管道(Pipe)及有名管道( ...

  8. 线程间同步之 semaphore(信号量)

    原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程间同步也可用于同一个进程间的线程同 ...

  9. (Java多线程系列二)线程间同步

    Java多线程间同步 1.什么是线程安全 通过一个案例了解线程安全 案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 先来看一个线程不安全的例子 class Sell ...

  10. linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图:  一.互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...

随机推荐

  1. MySQL常用简单小命令

    1. 登录数据库: mysql -h localhost -u root -p

  2. ytu 1041: 迭代法求平方根(水题)

    1041: 迭代法求平方根 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 227  Solved: 146[Submit][Status][Web Bo ...

  3. Diskpart命令安装系统小结

    <diskpart命令安装系统小结> 今天给同学安装系统,win8改win7.同学是预装了win8的联想y480,分区表采用的是GPT格式,捣鼓了半天才知道.GPT格式是新式的分区格式,相 ...

  4. PHP 常用正则汇总

     平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用:    }|d{})-((([-]{}))|([|]))-(([-]([-]{}))|([|]))$/   ([-]{}) ...

  5. kinect学习笔记(一)—— Openni平台的搭建~、

    一.简述         Openni平台是开源的平台,也就是说所有的源代码都可以查询,可以有助于我们对于整个程序框架的学习和理解,相对于微软的SDK,我更倾向于这个平台,但是由于个各种原因,现在这个 ...

  6. oracle创建临时表没有权限

    执行下面: grant create any table to 用户名称

  7. Javascript实现Linq查询方式

    Linq是.net平台一个重要的技术,全称Language Integrated Query.通过构建快速查询语句,可快速从数据库或集合中筛选数据集.以查询数据库相同的方式操作内存数据. 在ECMAS ...

  8. UVa10917 A Walk Through the Forest(SPFA+记忆化搜索)

    题目给一张有向图,问从起点1到终点2沿着合法的路走有种走法,合法的路指从u到v的路,v到终点的距离严格小于u到终点的距离. 先SPFA预处理出所有合法的路,然后这些路肯定形成一个DAG,然后DP一下就 ...

  9. 详解Adorner Layer(zz)

    首先,千万不要觉得Adorner离你很远,因为最简单的WPF界面也会用到Adorner.在WPF中,下面的几个很常见的功能,都是用Adorner实现的.     1. 光标(caret)     2. ...

  10. BZOJ3276 : 磁力

    按距离建立线段树,维护区间重量最小值 然后跑一遍拓扑,每次将所有能取的加入队尾 #include<cstdio> #include<algorithm> #define N 2 ...