• 读写锁分离的循环队列


    在很多需要高性能的场合下,锁的设计一直是一个比较关键的问题。无锁队列、读写锁分离的队列在业界以及学术界都已经有很成熟的研究。在网上也有很多资料,但其实有很多实现都是错误的。最近在工作中帮忙追查一个线上问题时,就发现实现一个正确的版本是比较困难的事情。 

          背景:实现一个循环队列,队列长度已预先分配。支持不同线程的多写多读。

          原本的实现是对读和写分别使用了两个不同的锁来提升性能,但是在最早实现的时候并没有发现到线程间数据的同步修改会造成小概率读取脏数据导致线上服务有问题

    复制代码
     1 size_t Queue::pop(int &value)
    2 {
    3 AutoLock lock(_poplock);
    4 if (!empty()) {
    5 value = _queue[_read];
    6 ++ _read;
    7 if (_read == _maxsize) {
    8 _read = 0;
    9 }
    10 return 1;
    11 }
    12 return 0;
    13 }
    14
    15 size_t Queue::push(int value)
    16 {
    17 AutoLock lock(_pushlock);
    18 if (!full()) {
    19 _queue[_write] = value;
    20 ++ _write;
    21 if (_write == _maxsize) {
    22 _write = 0;
    23 }
    24 return 1;
    25 }
    26 return 0;
    27 }
    复制代码

          出现的问题原因是 _read 和 _write 是存在非法的状态(_read = _max_size)。考虑这种场景当_read = _write=_max_size-1时,如果一个线程执行了push操作,并停在if (_write == _maxsize).但是由于线程间的切换,有两个线程继续执行了pop操作,那么就存在一个线程取到了脏数据。

          修改的方法可以两种:1 将读写锁合并成一个锁,但是会降低性能 2 修改实现,使 _read 和 _write不存在非法状态

    View Code

     

  • 相关阅读:
    js获得动态生成的标签
    自定义字段在List和ClassList等标签里的使用方法
    asp.net dropdownlist 取不到值
    MXCMS新增标签IFrame 包含标签
    JS打印
    Flash图表解决方案 Finger Chart
    推荐个免费的客户端控件
    C#利用反射获取对象属性值
    位置导航MXCMS Position标签说明
    OAuth简介
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8541347.html
Copyright © 2020-2023  润新知