队列,循环队列,乒乓队列区别

柔情痞子 提交于 2019-12-15 19:49:37

很久以前就想说一说这哥仨的区别了,可是奈何懒癌间歇性发作,对这个task是视而不见,汗颜。。好了,废话不说了,进入正题。

首先,先看最基础的队列:

队列嘛,内部使用数组实现的话,无非是从头部读取,在尾部插入

但是有一个缺点,就是队列经过若干次的读取后,前面明明还有空间,却不能再使用了

解决这个问题的直观办法就像这样

 

 

 就是每删除一个头,后面的所有元素往前移动一位。现实生活中的确是这样,前面的人走了,后面的人顶上去。

但是,这个方法是有问题的,这种方法带来了复制元素的开销,当队列很大时,将会带来严重的性能问题。

因此,为了解决这个问题,循环队列(也叫循环缓冲区)应运而生。其特点是,使用读指针和写指针来完成队列头和队列尾部的判断

这样就没有了复制元素带来的开销了,本质上还是对一个队列的读写过程的优化和改进。

 

那么乒乓缓冲区又是什么鬼呢,它对应的是个什么场景呢?

我们思考这样一件事,串口的数据通过DMA搬到一个buffer里面,然后在搬运的过程没有结束的时候,一般不能操作这个buffer,只有等搬运完毕

等到DMA中断才可以进行操作。但是,这段时间CPU相当于就被浪费掉了,啥事也没干。这显然是算力的浪费(这里指的是单任务环境下),而且,CPU开始处理后,

那下一帧数据又来了咋办呢,毕竟我们又不能预料什么时候会发生串口中断,那上一帧数据岂不是被破坏了吗?这个时候有人可能说了,你整个队列不就行了吗。

的确,这是一个解决办法。

网上找的一段话提供了另一个思路

具体过程是:当串口 BUF1 满了时,DMA 的目标地址迅速切换到 BUF2,此时可以处理

BUF1 的数据;当串口 BUF2 满了时,DMA 的目标地址迅速切换到 BUF1,此时可以处理 BUF2

的数据。如此一直循环下去,就像打乒乓球一样,你推我挡,故称作乒乓缓冲

这就是乒乓缓冲区的原理,但是,其实,我认为这里还有一个问题没有指出来,那就是,buff2满了的时候,要切换到buff1,那如果这个时候buf1还没有处理完成怎么办呢?

所以我觉得还是应该用队列来处理上面的这个场景。不知道作为读者的你有何看法,反正我觉得上面的引用里的说辞不能说服我。如果有更好的解释,欢迎在下方留言或评论。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!