C++无锁数据结构实现示例详解

 更新时间:2023年12月27日 09:11:05   作者:kkkK2008  
这篇文章主要为大家介绍了C++无锁数据结构实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

无锁数据结构

无锁并非真正无锁,正如零拷贝并非零次拷贝。

实现

多生产者多消费者队列

// 基于自旋锁(或者CAS,原理相同,后者实现较为复杂)
// 通过atomic库中atomic_flag类进行实现自旋达到多生产者多消费者同步。
#include <iostream>
#include <atomic>
class Queue {
    atomic_flag spin_push_flag = false, spin_pop_flag = false;
public:
       void Push() {
        // 自旋+上锁
        while (spin_push_flag.test_and_set())
            ;
        // working...
        // 解锁
        spin_push_flag.clear();
    } 
    void Pop() {
        // 自旋+上锁
        while (spin_pop_flag.test_and_set())
            ;
        // working...
        // 解锁
        spin_pop_flag.clear();
    }
};

单生产者单消费者队列

// 类似内核kfifo
#include <iostream>
#include <mutex>
class Queue {
private:
    mutex mutex_push, mutex_pop;
public:
       void Push() {
        lock_gurad<mutex> lck(mutex_push);
        // working...
    } 
    void Pop() {
        lock_gurad<mutex> lck(mutex_pop);
        // working...
    }
};

测试

前提

每次主线程十次循环建立100个线程访问队列,即1k线程并发。取100次平均值。一共三个版本:互斥锁单线程访问a、单生产者单消费者b、多生产者多消费者c

场景结果
Push和Pop接口不工作a和b时间相仿;c是前二100倍
Push和Pop接口处理一些简单工作a和b时间相仿;c是前二的10倍
Push和Pop接口处理一些较耗时工作b最快;c其次,为b的2倍;a最慢,为b的7-8倍

总结

综合来看:单生产者单消费者模型效率最优(Linux内核kfifo)。不过具体使用何种模型实现线程安全,要根据实际场景进行选择,并且多测试,才能够达到最佳模型的选择。此处仍有一点未提及:若要实现多线程并发访问数据结构,即单生产者单消费者或者多生产者多消费者,仍需要尽量避免共同数据的访问防止segment fault。

以上就是C++无锁数据结构的详细内容,更多关于C++无锁数据结构的资料请关注脚本之家其它相关文章!

相关文章

  • sigsetjmp的用法总结

    sigsetjmp的用法总结

    sigsetjmp()会保存目前堆栈环境,然后将目前的地址作一个记号,而在程序其他地方调用siglongjmp()时便会直接跳到这个记号位置,然后还原堆栈,继续程序的执行
    2013-09-09
  • C语言约瑟夫环的实现

    C语言约瑟夫环的实现

    这篇文章主要介绍了C语言约瑟夫环的实现的相关资料,这里主要是利用数据数据结果中循环链表来实现,需要的朋友可以参考下
    2017-08-08
  • C++实现模拟shell命令行(代码解析)

    C++实现模拟shell命令行(代码解析)

    这篇文章主要介绍了C++实现模拟shell命令行,本文通过实例代码进行命令行解析,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 使用C语言实现vector动态数组的实例分享

    使用C语言实现vector动态数组的实例分享

    vector是指能够存放任意类型的动态数组,而C语言中并没有面向对象的C++那样内置vector类,所以我们接下来就来看一下使用C语言实现vector动态数组的实例,需要的朋友可以参考下
    2016-05-05
  • c++插入排序详解

    c++插入排序详解

    插入排序的基本思想是每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。下面我们来详细探讨下C++实现插入排序
    2017-05-05
  • C++实现字符串类型相互转换的代码示例

    C++实现字符串类型相互转换的代码示例

    在C/C++编程中,字符串是非常基础且常用的数据类型,但是由于不同的编程语言或标准库可能采用不同的字符串类型,因此在不同的应用场景下可能需要进行字符串类型的相互转换,本文将介绍如何在C/C++中将char*,std::string,QString,CString/MFC String相互转换
    2023-06-06
  • C语言修炼之路函数篇真题训练上

    C语言修炼之路函数篇真题训练上

    函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数
    2022-03-03
  • C++类继承时的构造函数

    C++类继承时的构造函数

    这篇文章主要介绍了C++类继承时的构造函数,C++中,子类继承父类除去构造函数和析构函数以外的所有成员。因此,子类需要编写自己的构造函数和析构函数。更多相关详情需要的小伙伴可以参考下面文章介绍
    2022-03-03
  • 关于C++面向对象设计的访问性问题详解

    关于C++面向对象设计的访问性问题详解

    这篇文章主要给大家介绍了关于C++面向对象设计的访问性问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • 纯C语言:递归组合数源码分享

    纯C语言:递归组合数源码分享

    这篇文章主要介绍了纯C语言:递归组合数源码,有需要的朋友可以参考一下
    2014-01-01

最新评论