美文网首页
7.信号量的使用2021-11-01

7.信号量的使用2021-11-01

作者: 宜居远控 | 来源:发表于2021-11-01 16:23 被阅读0次

信号量相当于裸机中的标志 

信号量可以由不同的线程释放,互斥量必须由相同的线程释放。

信号量:实现线程间的通信,同步或临界资源的互斥访问。多线程系统中,线程间需要同步或互斥实现临界资源保护。二值信号量:用于线程间、线程与中断间的同步。其他线程获取,信号量为0,释放信号量为1。二值信号量最大计数值为1。也就是信号量的个数最大为1。是计数型信号量的特殊情况(计数最大值为1)。

注意 信号量的获取是一种阻塞式的  就是没有获取到信号量 就不会向下执行,这个线程被信号量挂起

看下面代码,如果别的线程没有释放信号量,虽然us_flag等于RT_EOK  但不会往下执行 

相当于rt_sem_take ()获取到一次信号量  程序才会向下执行一次 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

while(1)

{

us_flag=rt_sem_take(syn_sem, RT_WAITING_FOREVER);//这里被阻塞了  这个线程被信号量挂起

if(us_flag==RT_EOK)   //都不会往下执行

{

tt++;   //不会执行++

rt_thread_mdelay(400);

rt_mq_send( msg_mq, // 写入(发送)队列的ID(句柄)

            &filtered_val,  // 写入(发送)的数据所对应地址

            sizeof(filtered_val)// 数据的长度

                );

if(tt>=20){ us_flag=RT_EBUSY;tt=0;}

}

else

rt_thread_mdelay(400);

}

正确写法如下:   因为 rt_sem_take(syn_sem, RT_WAITING_FOREVER); 会死等信号量释放  线程会被挂起

/********************************************************************************************************************************

线程入口

*******************************************************************************************************************************/

static void Send_P01_thread_entry(void *parameter)

{

    while(1)

{

//rt_thread_mdelay(300);

rt_sem_take(syn_sem, RT_WAITING_FOREVER);

rt_mq_send( msg_mq, // 写入(发送)队列的ID(句柄)

            &filtered_val,  // 写入(发送)的数据所对应地址

            sizeof(filtered_val)// 数据的长度

                );

AT32_LEDn_Toggle(LED1);

}

}


释放信号量函数会将调用恢复阻塞态线程的函数,同时会调用调度函数执行线程调度。

二值信号量:若还有因读信号量而被阻态的线程,那只能等被阻态的所有线程都就绪后,再次释放才能真正释放。比如,我二值信号量我设定初始值为0,然后有个线程获取它,那个线程就会挂起,然后等中断里释放这个信号量时,“释放”的操作是这样的:若有因这个信号量而阻塞的线程则先恢复这个线程并执行一次调度——但此时是信号量这个值和线程恢复二选一的,若存在阻塞的线程,那么释放信号量时其值就不累加了。所以不是说释放二值信号量它的值就会++!不是说释放二值信号量它的值就会++!不是说二值信号量释放它的值就会++! 而是在没有阻塞情况下,是++的,在有阻塞线程下,不++的,而是先恢复线程的!

二值信号量特性:(1)前提是要先创建信号量。(2)获取和释放要成对出现。(3)读取未被释放好的二值信号量的所有线程都会被移除就绪表而被挂起,同时这些线程又会按照FIFO先进先出或者优先级的顺序被挂到这个二值信号量控制块下的成员suspend链表下。调用释放函数时从suapend的next恢复掉一个线程——而不是一下子恢复掉所有线程,一个一个来!(4)二值信号量的意义:这样子就完成了第一个线程中获取信号量函数到释放信号量函数之间的代码运行完了,才能再去运行下个获取同样这个信号量的线程中获取和释放的这部分代码。以此类推。假如把获取信号量和释放信号量这个区间当成代码区间。理想的执行顺序:先运行存在这种区间的最高优先级线程的区间1这段代码,再运行次高优先级线程的区间2,在运行第3高优先级线程的区间3,……,直到最后用到这个二值信号量的线程中的区间n。实际上的运行顺序还得根据延时时间动态判断。

————————————————

版权声明:本文为CSDN博主「huibin.yun」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/yhb1206/article/details/102595708

相关文章

  • 7.信号量的使用2021-11-01

    信号量相当于裸机中的标志 信号量可以由不同的线程释放,互斥量必须由相同的线程释放。 信号量:实现线程间的通信,同步...

  • iOS进阶-GCD信号量-dispatch_semaphore_

    目录 GCD信号量概念 使用API 实例使用 GCD信号量概念 使用API : dispatch_semaphor...

  • iOS底层--GCD应用

    手动目录GCD简介信号量信号量的理解信号量的使用信号量的代码实操信号量阻塞哪里的任务?栅栏函数dispatch_b...

  • [java并发编程]基于信号量semaphore实现限流器

    [TOC] 一、什么是信号量 “信号量”在编程术语中使用单词semaphore,那什么是“信号量”?信号量就好比你...

  • java concurrency <信号量>

    java concurrency <信号量> 使用信号量的目的 线程信号量的目的是使线程能够彼此发送信号。 此外,...

  • 信号量

    信号量的使用: 信号量使用的业务场景: 一、锁 YYKit加锁代码: 二、异步返回 三、控制并发量,降低性能。

  • 信号量实现网络顺序执行

    信号量的方式实现 CODE CODE ANALYSIS 使用信号量需要注意,dispatch_semaphore_...

  • Java中的管程模型

    操作系统使用信号量解决并发问题,Java选择使用管程(Monitor)解决并发问题。信号量和管程是等价的,可以使用...

  • 信号量

    信号量的使用,其实就是把异步变同步,信号量=0时等待执行,执行完之后把信号量+1,当信号量>0时就可以顺序执行了。...

  • iOS多线程异步信号量

    使用GCD信号量写了一个小demo,在不使用调度组和线程依赖的情况下,可以使用信号量git链接: https://...

网友评论

      本文标题:7.信号量的使用2021-11-01

      本文链接:https://www.haomeiwen.com/subject/nemzaltx.html