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

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

  1. #include <rtthread.h>
  2. #include <stm32f10x.h>
  3. #include "test.h"
  4.  
  5. rt_uint32_t g_tmp;/* 定义一个全局变量*/
  6.  
  7. /* 变量分配4字节对齐 */
  8. ALIGN(RT_ALIGN_SIZE)
  9.  
  10. /* 静态线程的 线程堆栈*/
  11. static rt_uint8_t thread1_stack[];
  12. static rt_uint8_t thread2_stack[];
  13.  
  14. /* 静态线程的 线程控制块 */
  15. static struct rt_thread thread_test1;
  16. static struct rt_thread thread_test2;
  17.  
  18. static void test1_thread_entry(void* parameter);
  19. static void test2_thread_entry(void* parameter);
  20.  
  21. void demo_thread_creat(void)
  22. {
  23. rt_err_t result;
  24.  
  25. /* 创建静态线程 : 优先级 16 ,时间片 2个系统滴答 */
  26. result = rt_thread_init(&thread_test1,
  27. "test1",
  28. test1_thread_entry, RT_NULL,
  29. (rt_uint8_t*)&thread1_stack[], sizeof(thread1_stack), , );
  30.  
  31. if (result == RT_EOK)
  32. {
  33. rt_thread_startup(&thread_test1);
  34. }
  35.  
  36. /* 创建静态线程 : 优先级 15 ,时间片 1个系统滴答 */
  37. result = rt_thread_init(&thread_test2,
  38. "test2",
  39. test2_thread_entry, RT_NULL,
  40. (rt_uint8_t*)&thread2_stack[], sizeof(thread2_stack), , );
  41.  
  42. if (result == RT_EOK)
  43. {
  44. rt_thread_startup(&thread_test2);
  45. }
  46.  
  47. }
  48.  
  49. void test1_thread_entry(void* parameter)
  50. {
  51. rt_uint32_t i;
  52.  
  53. /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
  54. rt_enter_critical();
  55.  
  56. g_tmp = ;
  57. rt_kprintf("g_tmp=:%d \r\n", g_tmp);
  58. for(i=; i<; i++)
  59. {
  60. g_tmp++;
  61. }
  62. rt_kprintf("g_tmp=:%d \r\n", g_tmp);
  63.  
  64. /* 调度器解锁 */
  65. rt_exit_critical();
  66. }
  67.  
  68. void test2_thread_entry(void* parameter)
  69. {
  70. rt_thread_delay();//
  71. g_tmp++;
  72. }

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

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. .net自定义事件,经典简单实例代码

    1,新建一个控制台应用程序TestDelegate,本项目主要实现:热水器加热,报警器监控,当热水温度达到80度的时候报警器报警这样一个简单的事件处理程序 2,定义委托处理程序 public dele ...

  2. linux tricks 之 typeof用法.

    typeof是gcc的扩展功能,比较简单,是用来取得参数类型,具体可参考gcc官网的解释. https://gcc.gnu.org/onlinedocs/gcc/Typeof.html ------- ...

  3. MQ的通讯模式

    1) 点对点通讯:点对点方式是最为传统和常见的通讯方式,它支持一对一.一对多.多对多.多对一等多种配置方式,支持树状.网状等多种拓扑结构. 2) 多点广播:MQ适用于不同类型的应用.其中重要的,也是正 ...

  4. EAS使用中FineUI的配置

    <?xml version="1.0" encoding="utf-8"?> <configuration> <configSec ...

  5. hdu 4185 二分图匹配

    题意用1*2的木板覆盖矩阵中的‘#’,(木板要覆盖的只能是‘#’),问最多能用几个木板覆盖 将#抽象为二分图的点,一个木板就是一个匹配,注意最后结果要除以2 Sample Input 1 6 .... ...

  6. loadrunner个版本历程

    1.工具介绍: LoadRunner是一种预测系统行为和性能的负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题, LoadRunner能够对整个企业架构进行测试.通过 ...

  7. finally 语句

    package unit5; public class FinallyDemo { int no1,no2; public FinallyDemo(String[] args) { try{ no1= ...

  8. js上传和预览图片

    [1].[代码] [HTML]代码 跳至 [1] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  9. JVM的GC理论详解

    GC的概念 GC:Garbage Collection 垃圾收集.这里所谓的垃圾指的是在系统运行过程当中所产生的一些无用的对象,这些对象占据着一定的内存空间,如果长期不被释放,可能导致OOM(堆溢出) ...

  10. 关于配置文件权衡,.config VS .xml

    众所周知,程序的灵活性有一部分就是“配”出来了. 当然,config文件从来就没有让.NET的同学轻松过,至少,我觉得很麻烦. 1.config .NET的配置文件方便,其实最方便的是appSetti ...