linux多对多无锁队列,多线程无锁队列实现思路

本文是基于单生产者单消费者线程的实现。

struct {

char buf[65536];

unsigned short writer_index;

unsigned short reader_index;

}

reader_index只由读线程改变,writer_index只由写线程改变。

读线程读取reader_index到writer_index之间的数据,读取完毕向前移动reader_index。发现writer_index小于reader_index,读线程读取数据直到队列结尾,并将reader_index移到队列开头,继续读取。

写线程计算检查可用写空间,将数据写入,并移动writer_index。当写到队列结尾,将writer_index移动到队列开头,再从头开始写。

读线程看到的writer_index不一定是最新的,但不会导致读取错误数据,只是会比应该读取的少读一些。

写线程看到的reader_index不一定是最新的,但不会导致写入错误,只是会比应该写入的少写一些。

需要注意的是cpu对指令的乱序执行以及cpu间cache同步乱序问题。

1.cpu完全可以先将写指针移动,然后再写入数据,这样的执行顺序对于单线程没有任何影响。对于我们现在这种模型,读线程就有机率读取到错误的数据。同样读线程先执行读指针移动,后读取数据,会有机率导致还没有读出的数据被写线程写入覆盖。

2.cpu间数据同步数据可能乱序。比如cpu1修改了a和b,同步给cpu2,a和b到达cpu2的顺序不确定。如果读线程写线程分处于两个不同cpu执行,有机率出现1问题中同样的错误,即读线程先看到了写指针的改变,并读取了还没有被写入的脏数据。

解决方法就是给cpu使绊,使用memory barrier(内存屏障)让cpu必须顺序执行指令,并保证同步顺序。关于memory barrier的用法可以自行google,也可以关注我的下一篇关于内存屏障的使用介绍。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值