优化设计-任务间通信-用队列而不用缓冲区
近期接手了一个别人的软件,vxworks下的项目。
代码看了看,没有发现啥毛病。但是运行时,总是会发现“卡死”现象。能ping通,能建立连接,似乎还活着,但是不能正确响应原有某些请求。
又细看了下代码,请求相关的有2个任务,暂且称为A和B。A用于接收数据,然后放入缓冲区,然后B任务从缓冲区取数,并根据数据进行处理。
A和B都用到了缓冲区,于是加了个互斥量,A与B都访问缓冲区时互斥下。
B任务是一个while循环,每隔10ms就去获取互斥量,如果收到数就进行处理。
乍一看,没啥毛病的,但是细分析下,还是很粗糙的。
1、效率问题
B任务用轮循,每隔10ms就去查一次互斥量,明显消耗CPU资源较大。正确的做法应该是收到数据才通知B任务进行处理。
2、任务的调度与饿死现象
B任务轮循,而且间隔很短,很有可能在某一个时间段,A任务就是无法获取到互斥量,导致A任务饿死。从而造成假死现象。
3、好的设计范式
优先使用队列而不使用缓冲区。
这种模式就应该用一个消息队列来进行任务间通信。
B任务死等A任务发过来的消息。没有就死等。如果有消息过来,就进行处理。
这样,B任务的处理是不会影响到A的,而且B任务消耗的资源会明显下降很多。
ps:术语 补充 本质
广义上来讲,一个队列也可以是一个缓冲区。有些较好的设计中就是用队列、或者环形队列来作为缓冲区进行任务间通信。
所以,从本质上来讲,本篇文章想说的是让对同一个缓冲区的读写操作互不影响,可以并行。