20191010 (21) RT-Thead 线程同步

目的

1 理解基本的多线程交互概念


正文

1 什么时候需要涉及到线程同步的概念
当线程之间需要进行数据传递的时候,就需要考虑到线程同步的事情了,比如对同一变量进行读写。
但每次只允许一个线程进行操作,那就需要涉及到等待,互锁等概念。

线程的同步方式有很多种,其核心思想都是:在访问临界区的时候只允许一个 (或一类) 线程运行。进入 / 退出临界区的方式有很多种:
1)调用 rt_hw_interrupt_disable() 进入临界区,调用 rt_hw_interrupt_enable() 退出临界区;详见《中断管理》的全局中断开关内容。
2)调用 rt_enter_critical() 进入临界区,调用 rt_exit_critical() 退出临界区。本章将介绍多种同步方式:信号量(semaphore)、互斥量(mutex)、和事件集(event)。

信号量

你可以理解为厕所,只有厕所里的人出来(释放信号量),下一个排队的才能进入(捕获信号)。这样信号量值就不断在 0-5 之前切换

struct rt_semaphore { 
    struct rt_ipc_object parent; /* 继承自 ipc_object 类 */   
    rt_uint16_t value; /* 信号量的值 */ 
}; 
/* rt_sem_t 是指向 semaphore 结构体的指针类型 */ typedef struct rt_semaphore* rt_sem_t;

rt_semaphore 对象从 rt_ipc_object 中派生,由 IPC 容器所管理,信号量的最大值是 65535。

控制方式与之前一样

创建/初始化 rt_sem_create/init()
获取 rt_sem_take/trytake()
释放 rt_sem_release()
删除/脱离 rt_sem_delete/detach()

特别说明:
1 创建 决定信号量排队方式
RT_IPC_FLAG_FIFO(先进先出)
RT_IPC_FLAG_PRIO(优先级等待)

如果不想等待信号量,使用无等待信号量
rt_sem_trytake()

断与线程间的互斥不能采用信号量(锁)的方式,而应采用开关中断的方式


互斥量

优势:就是唯一性,它只管谁占有这个资源
举例:厕所里独立的坑位,只要有人占用,不管外面时谁都得老老实实等着,知道占用的人放弃使用为止。至于厕所外面的人排队,还是遵循谁牛逼谁在前

创建/初始化 rt_mutex_create/init()
获取 rt_mutex_take()
释放 rt_mutex_release()
删除/脱离 rt_mutex_delete/detach()

特别说明:
1 创建 决定信号量排队方式
RT_IPC_FLAG_FIFO(先进先出)
RT_IPC_FLAG_PRIO(优先级等待)

需要切记的是互斥量不能在中断服务例程中使用


事件集

①P1 坐公交去某地,只有一种公交可以到达目的地,等到此公交即可出发。
②P1 坐公交去某地,有 3 种公交都可以到达目的地,等到其中任意一辆即可出发。
③P1 约另一人 P2 一起去某地,则 P1 必须要等到 “同伴 P2 到达公交站” 与“公交到达公交站”两个条件都满足后,才能出发。
这里,可以将 P1 去某地视为线程,将 “公交到达公交站”、“同伴 P2 到达公交站” 视为事件的发生,情况①是特定事件唤醒线程;情况②是任意单个事件唤醒线程;情况③是多个事件同时发生才唤醒线程。

创建/初始化 rt_event_create/init()
获取 rt_event_send()
释放 rt_event_recv()
删除/脱离 rt_event_delete/detach()

使用 32 位的无符号整数来标识事件集,它的每一位代表一个事件,因此一个事件集对象可同时等待接收 32 个事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值