数据通信过程的免锁设计

# 数据通信过程的免锁设计

数据通信过程一般都会用到buffer,为了保持数据一致性,通常会加锁保护。

是否真的需要加锁保护,需要分析buffer的具体使用场景。

buffer数据使用可以分为两个角色:生产者(存入者)和消费者(读取者)。 生产者和消费者分别在数据的前后两端操作buffer。

作为生产者添加数据之前获取 可用空间,加入此时有消费者在读取数据,可用空间只会增大,不会影响数据添加。反之,消费者在读取数据之前获取可读取数据,如果同时又生产者向缓存中添加数据,并不会影响消费者读取。

所以对于一个具体buffer而言,这两个角色在系统中具有唯一性,就可以做到免锁设计。 如果存在多个,则需要加锁保护,避免添加的数据互相覆盖或者消费的数据重复读出。

对于uart通信来说,中断处理程序就是其接收buffer唯一的生存者,发送buffer唯一的消费者,这样,它就可以自由的在buffer的一端进行操作,而不会对数据产生影响。

这里一般会考虑到buffer空间在操作过程是否有溢出覆盖的问题。

对于这个问题有成熟的解决方案,就是环形buffer的设计。

环形buffer有一个head和end指针分别用于生产者和消费者操作buffer的输入和输入的其中一端,只要这个环形buffer设计的没问题,就不用担心数据一致性问题。

如果考虑到串口数据接收不及时造成的数据丢失,这是另外一个问题,可以有硬件流控解决。

一个锁如果角色过多,设计就会混乱。

在多核情况下,用自旋锁实现原子操作,在中断里面是可以用的。原子操作不会导致调用者挂起。其他情况则不能使用,尤其持有自旋锁的过程再去申请其他锁。阿里的代码就存在这种使用。自旋锁要求每个核持有时间必须尽可能短,否则多核运行都被自旋锁串行化了,多核的性能就体现不出来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值