信号量
信号量是最基本的通信原语,可用于线程同步、事件通知、共享数据保护,包括二值信号量和计数信号量,在非嵌入式系统中,信号量还被用于进程间通信。
eCos的计数信号量包含了两个实现,分别为Cyg_Counting_Semaphore和Cyg_Counting_Semaphore2。Cyg_Counting_Semaphore是可抢占的,而Cyg_Counting_Semaphore2是不可抢占的。Cyg_Counting_Semaphore2总是唤醒等待队列的第一个线程并且该线程百分百得到了该信号,而Cyg_Counting_Semaphore在信号post时会唤醒等待队列的第一个线程,但是在唤醒该线程和该线程得到CPU控制权之间有一段时间,如果在这段时间内有更高优先级的线程希望获得该信号,那么该信号被更高优先级的线程获得,由post唤醒的线程获得CPU控制权后发现信号量被抢占继续回到等待状态。cyg_semaphore_* API函数封装的是可抢占的Cyg_Counting_Semaphore实现。
互斥量
互斥量主要用于共享数据保护,使用信号量进行共享数据保护时会存在优先级反转的问题,互斥量解决了优先级反转问题,互斥量只能由加锁的线程进行解锁,有些实现还支持嵌套加锁。
eCos的互斥量不支持嵌套加锁,如果嵌套加锁那么将导致死锁,使用eCos的POSIX兼容层API时如果嵌套加锁将返回错误码。eCos互斥量可以通过配置指定使用优先级置顶协议或优先级继承协议处理优先级反转问题,也可以不进行任何优先级反转处理或在运行时指定。
互斥量相比信号量特有的特性包括:优先级反转问题的处理(提高实时性)、必须由同一线程加锁和解锁。
条件变量
条件变量是与互斥量相关联的用于多线程之间关于共享数据状态改变的通信机制,是唯一支持广播的同步原语,支持一个事件源唤醒多个线程,某些情况下可以使用信号量代替条件变量,但不能完全代替。大部分eCos驱动程序使用条件变量在DSR与线程之间传递消息,以太网驱动使用信号量传递消息。
条件变量相比信号量特有的特性包括:解锁和挂起是原子操作(更加安全和便捷)、支持广播(同时唤醒多个线程)、如果没有线程正在等待那么丢弃事件消息、资源可用数由调用者而非同步原语控制(提高效率)。使用信号量必须在每次使用资源前调用信号量wait函数,而条件变量只需要在资源不可用的情况下调用wait函数,在资源可用的情况下,直接使用资源而无需调用wait函数,明显条件变量的效率比信号量更高。在某些情况下条件变量比信号量更灵活。条件变量可以说是同步原语中最复杂的一个,其它同步原语都可以单独使用,唯独这个条件变量要配合互斥量使用,从这点就可以反映出其复杂度。
事件标志
事件标志用于一个线程等待多个事件,可以对多个事件进行与/或,在多个事件全部满足(与)或者多个事件中的任意一个以上满足(或)时唤醒等待线程。eCos的select函数就是使用事件标志实现的,而lwIP的select是使用信号量实现的。使用信号量可以实现多个事件相或的情况,但是不能实现多个事件相与的情况。
邮箱
邮箱用于线程间数据传递,邮箱维护一个固定数目的void*指针队列,队列大小在编译时确定。邮箱使用的是先进先出(FIFO)队列。邮箱是嵌入式实时系统线程间数据传递的首选,大部分RTOS都实现了邮箱通信机制,eCos也不例外。
消息队列
消息队列的作用与邮箱相同,用于线程/进程间数据传递,但与邮箱不同的是,消息队列传递的不是void*指针,而是所有数据,消息队列在创建时根据最大数目和大小动态分配缓存空间,发送的数据首先拷贝到缓存空间内,接收数据时从缓存空间拷贝数据。消息队列支持线程间通信和进程间通信,很显然更适合于进程间通信,如果使用消息队列做线程间通信,相当浪费,因为要拷贝数据两次,线程间数据传递应当使用邮箱。消息队列使用优先级队列,每个消息包含一个优先级参数。eCos中的消息队列主要是为了实现POSIX兼容层的消息队列。
POSIX同步原语
POSIX兼容层的同步原语包括信号量、互斥量、条件变量、消息队列,不包括事件标志和邮箱。
标签:简要,优先级,队列,信号量,互斥,原语,线程,eCos From: https://blog.51cto.com/zoomdy/5872035