首页 > 编程知识 正文

记录型信号量机制,分组交换和报文交换的区别

时间:2023-05-05 18:47:54 阅读:113412 作者:1482

1 .信号量有两种。 计数性信号量和二值信号量。 可以多次获取计数性信号量。 二值信号量只有0和1两种状态,只能获取一次。

信号可以用于保护资源,防止多个任务同时访问资源。 为资源创建专用的二进制信号量。 任务在申请访问资源之前先申请获取信号量。 如果当前没有任务访问资源,则信号量获取成功,并且可以继续访问资源。 如果当前资源由某个任务访问,则信号获取失败,任务处于挂起状态,其他任务访问并完成资源,释放信号,然后访问资源。

如果一个资源允许同时访问多个任务,则可以采用计数器信号,每当任务申请获取信号时,将信号数量减少一个,减少到0,然后以信号的初始值同时访问资源,直到不允许重新获取其他任务

2 .优先级反转使用信号量可能导致优先级反转的问题。 详细说明请参照下图。 这是从RT-Thread编程指南中截取的,简单来说,当一个高优先级任务申请访问资源时,由于资源被低优先级任务占用,高优先级任务被挂起。 在这种情况下,如果一个中优先级任务已准备就绪,并且剥夺了低优先级任务的CPU使用权并开始运行,则该任务将先于高优先级任务运行

3 .互斥量互斥量可以是二进制信号量,高优先级任务申请访问资源,但资源分配给低优先级任务时,将低优先级任务的优先级提高到与高优先级相同的级别,从而在中优先级任务准备就绪时剥夺低优先级任务的CPU使用权详细说明请参照下图。 任务申请获取排他量时,系统判断当前占用此排他量的任务优先级和申请任务优先级,如果申请任务优先级更高,系统将此更高优先级分配给占用排他量的任务,并在任务释放排他量时恢复到原始优先级。

互斥量还支持重新输入,即多次获取,在这种情况下,获取多少次互斥量需要释放多少次才能完全释放? 且排他量属于某个任务,其他任务不能释放哪个任务获得排他量、哪个任务释放排他量。

4 .死锁(也称为死锁)是指无限制地等待两个任务占用的资源。 详细说明后,从《嵌入式实时操作系统uC/OS-III》开始切取。

有三种方法可以避免死锁:

(1)按不同任务相同顺序申请多项资源; )如果任务需要使用多个资源,请在获取所有资源后再执行以下操作: )3)申请获取互斥量或信号量时设置超时时间,避免永远等待。 最有效的方法(1)是按照相同的顺序访问资源,这样可以避免两个任务和两个资源之间的交叉访问。 如果在任务中使用资源的顺序固定,则可以在获得所有资源的访问权限后再访问资源,从而避免死锁问题。 方法)3)虽然可以暂时避免死锁,但会导致系统错误,因此不推荐。

5 .邮箱和消息队列5.1 uCOS uCOS-II有两个概念:邮箱和消息队列,它们都是事件的一种。 对于邮箱来说,由于事件控制块中只有一个指针直接指向数据地址,因此一次只能传递一个数据指针。 对于消息队列来说,Event控制块中的指针指向消息队列,消息队列中的每个节点都包含一个数据地址,因此可以同时传递多个数据地址。 队列大小为1的消息队列与邮箱的作用相同。

uCOS-II有一个静态全局结构数组OSQTbl[OS_MAX_QS],其中包含系统中所有可用的消息队列,每次创建消息队列时,都会从该数组中检索节点。

在uCOS-III中,邮箱概念已被废除,只剩下消息队列。 在代码中,定义了消息池。

OS _ msgoscfg _ msg pool [ OS _ CFG _ msg _ pool _ size ]; 所有消息队列在发送消息时,都会从消息池中提取节点,并将其置于消息队列的消息链表中。 消息队列控制块还记录消息节点的数量,指针指向消息链表的开头和结尾。

消息队列控制块的定义如下:

structos _ msg _ q {/* OS _ msg _ q */OS _ msg * inptr;/* pointertonextos _ msgtobeinsertedinthequeue */OS _ msg * outptr;/* pointertonextos _ msgtobeextractedfromthequeue */OS _ msg _ qtynbrentriessize;/* maximumallowablenumberofentriesinthequeue */OS _ msg _ qtynbrentries;/* currentnumberofentriesinthequeue */OS _ msg _ qtynbrentriesmax;

/* Peak number of entries in the queue */}; 5.2 rt-thread

RTT中有邮箱和消息队列两个概念,它的邮箱和uCOS-II的邮箱概念不同。RTT的邮箱是基于一个数组来实现的,数组的成员是4字节变量,可以是数据地址或变量,这个数组就是该邮箱的消息池,在创建邮箱的时候固定进行分配。所以RTT的邮箱在传递数据时每次固定传输一个4字节的数据,每次发送邮件的时候从消息池中取一个4字节变量出来,接收邮件的时候释放一个4字节变量。邮箱控制块中存储着当前邮箱发送邮件(in_offset)和接收邮件(out_offset)的数据地址,以及当前邮箱中存在的邮件数量(entry)。

邮箱控制块的定义如下:

struct rt_mailbox{ struct rt_ipc_object parent; /**< inherit from ipc_object */ rt_ubase_t *msg_pool; /**< start address of message buffer */ rt_uint16_t size; /**< size of message pool */ rt_uint16_t entry; /**< index of messages in msg_pool */ rt_uint16_t in_offset; /**< input offset of the message buffer */ rt_uint16_t out_offset; /**< output offset of the message buffer */ rt_list_t suspend_sender_thread; /**< sender thread suspended on this mailbox */};

RTT消息队列的实现和uCOS相似。但RTT不再是所有消息队列共用一个消息池,而是每个消息队列单独有一个消息池,分别管理。

RTT的消息队列控制块定义如下:

struct rt_messagequeue{ struct rt_ipc_object parent; /**< inherit from ipc_object */ void *msg_pool; /**< start address of message queue */ rt_uint16_t msg_size; /**< message size of each message */ rt_uint16_t max_msgs; /**< max number of messages */ rt_uint16_t entry; /**< index of messages in the queue */ void *msg_queue_head; /**< list head */ void *msg_queue_tail; /**< list tail */ void *msg_queue_free; /**< pointer indicated the free node of queue */ rt_list_t suspend_sender_thread; /**< sender thread suspended on this message queue */};

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。