rt-thread信号量解释与举例使用

一、介绍信号量

        信号量是一种轻型的用于解决线程间同步问题的内核对象,线程可以获取或释放它,从而达到同步或互斥的目的。

        每个信号量对象都有一个信号量值和一个线程等待队列,信号量的值对应了信号量对象的实例数目、资源数目,假如信号量值为 5,则表示共有 5 个信号量实例(资源)可以被使用,当信号量实例数目为零时,再申请该信号量的线程就会被挂起在该信号量的等待队列上,等待可用的信号量实例(资源)。其实所谓的资源,简单举个例子说就是对某个变量的操作权。信号量就是有传递信息的作用,“量”就是是否还有可以操作某个资源(比如变量,也是一个资源)的权限,比如读写和赋值等。

        跟定时器和创建线程一样,都是一个套路,对信号量的操作也包含创建 / 初始化信号量、获取信号量、释放信号量、删除 / 脱离信号量,记住删除只能对应动态信号量,因为删除是连创建信号量时分配的内存一起删除,而静态只是脱离,不能再使用这个信号量,不能删除占用的内存。如果当前信号量的值是0,再有线程去申请,就会挂在在该链表上等待新的信号量数值,如果数值大于0,就会唤醒在该等待队列的线程,至于唤醒是优先级线程唤醒还是先进先出唤醒,要看创建线程时是设置的什么属性,举例子时我会注释出来。

三、信号量的使用示例

        thread1优先级比较高会先执行,正常情况下执行rt_kprintf("thread1test1\r\n")后又延时了时间应该切换到thread2执行rt_kprintf("thread2test1\r\n")打印,但是实际不会,因为到thread2时信号量的值为0了,获取不到资源所以执行不了,这就是信号量同步的作用。(Note:rt_kprintf是thread的API,默认输出到STM32F103C8T6的UART1)

#include "board.h"               //头文件合集
#include <stdio.h>

struct rt_thread thread1;
struct rt_thread thread2;
static rt_sem_t sem = RT_NULL;
rt_uint8_t thread1_stack[512]={0};
rt_uint8_t thread2_stack[512]={0};

static void thread1_callback(void *parameter)
{
	rt_err_t result = RT_EOK;
	while(1)
	{
		//注释掉信号量的获取和释放,两个线程的打印就会交替进行
		result = rt_sem_take(sem,RT_WAITING_FOREVER);//信号量值-1
		if(result != RT_EOK)
		{	
			return ;
		}
		rt_kprintf("thread1test1\r\n");
		rt_thread_delay(300);//延时300ms,让thread2可以去运行
		rt_kprintf("thread1test2\r\n");
		rt_sem_release(sem); //释放信号量,值+1
	}

}
static void thread2_callback(void *parameter)
{
	rt_err_t result = RT_EOK;
	while(1)
	{
		result = rt_sem_take(sem,RT_WAITING_FOREVER);
		if(result != RT_EOK)
		{	
			return ;
		}
		rt_kprintf("thread2test1\r\n");
		rt_thread_delay(300);//延时300ms,让thread1可以去运行
		rt_kprintf("thread2test2\r\n");
		rt_sem_release(sem);
	}

}

int main(void)
{
	/*T_IPC_FLAG_FIFO的意思是信号量值是0时,线程谁先等待等信号值不为0时就先唤醒谁
	1是初值为1*/
	sem = rt_sem_create("sem_demo",1,RT_IPC_FLAG_FIFO);
	rt_thread_init(&thread1,
	"thread1",
	thread1_callback,
	NULL,
	&thread1_stack[0],
	sizeof(thread1_stack),
	7,
	5);
	/*5是时间片,作用是当有相同优先级的线程时,最大执行时间是5 tick
	如果线程毁掉函数执行时间少于5 tick,也会提前返回,切换带到下一个线程
	如果5 tick还没执行完也会切换到下一个线程	*/
	rt_thread_init(&thread2,
	"thread2",
	thread2_callback,
	RT_NULL,
	&thread2_stack[0],
	sizeof(thread2_stack),
	8,
	5);	
	//开启两个线程
	rt_thread_startup(&thread1);
	rt_thread_startup(&thread2);
	
	return 0;
}

加上信号量有不同的效果,看打印。有信号量是执行完thread1后释放信号量thread2检测到信号量值不为0执行后面的打印。无信号量是thread1和thread2轮流执行,交替打印。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蛋骗鸡~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值