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++无锁数据结构的资料请关注脚本之家其它相关文章!
最新评论