c++ 无锁队列的简单实现

无锁队列的基本介绍

一个关于无锁队列的多线程读写代码示例。在这里,我提供一个简单的示例来说明这个问题。
在使用无锁队列时,需要注意以下几点:
使用原子操作来实现对队列的读写操作,以避免多线程同时访问同一数据导致的竞争条件问题。
当队列为空或已满时,需要使用特殊的标记来表示队列的状态。
使用链表来实现的无锁队列
下面是一个使用无锁队列的多线程读写代码示例:

#include <atomic>
#include <thread>
#include <iostream>
template <typename T>
class LockFreeQueue
{
public:LockFreeQueue() : m_head(new Node), m_tail(m_head.load()) {}~LockFreeQueue(){while (Node* const old_head = m_head){m_head = old_head->next;delete old_head;}}void enqueue(T value){Node* const new_node = new Node(value);Node* old_tail = m_tail.exchange(new_node);old_tail->next = new_node;}bool dequeue(T& value){Node* old_head = m_head;Node* new_head;do{if (old_head->next == nullptr){return false;}new_head = old_head->next;} while (!m_head.compare_exchange_weak(old_head, new_head));value = new_head->value;delete old_head;return true;}
private:struct Node{T value;Node* next;Node() : next(nullptr) {}Node(T value) : value(value), next(nullptr) {}};std::atomic<Node*> m_head;std::atomic<Node*> m_tail;
};
int main()
{LockFreeQueue<int> queue;std::thread t1([&queue](){for (int i = 0; i < 10; ++i){queue.enqueue(i);}});std::thread t2([&queue](){int value = 0;while (value < 9){if (queue.dequeue(value)){std::cout << "Dequeued value: " << value << std::endl;}}});t1.join();t2.join();return 0;
}

这段代码实现了一个无锁队列,其中enqueue()函数用于向队列中添加元素,dequeue()函数用于从队列中取出元素。在这个示例中,我们使用了C++11中的std::atomic来实现原子操作,以确保多线程访问时的线程安全。同时,我们使用了compare_exchange_weak()函数来确保多线程环境下的原子操作。

以环形队列实现无锁队列

#include <atomic>
template <typename T>
class LockFreeQueue {
public:LockFreeQueue(size_t capacity = 1024) : m_capacity(capacity) {m_data = new T[m_capacity];m_head.store(0, std::memory_order_relaxed);m_tail.store(0, std::memory_order_relaxed);}~LockFreeQueue() {delete[] m_data;m_data = nullptr;}bool push(const T& item) {size_t tail = m_tail.load(std::memory_order_relaxed);size_t head = m_head.load(std::memory_order_acquire);size_t count = tail - head;if (count >= m_capacity - 1) {return false;}m_data[tail % m_capacity] = item;m_tail.store(tail + 1, std::memory_order_release);return true;}bool pop(T& item) {size_t head = m_head.load(std::memory_order_relaxed);size_t tail = m_tail.load(std::memory_order_acquire);size_t count = tail - head;if (count == 0) {return false;}item = m_data[head % m_capacity];m_head.store(head + 1, std::memory_order_release);return true;}
private:T* m_data;size_t m_capacity;std::atomic<size_t> m_head;std::atomic<size_t> m_tail;
};

这个队列是一个环形队列,使用了两个原子变量 m_headm_tail 分别表示队列头和队列尾,通过利用原子操作保证线程安全,实现了无锁的操作。同时,使用了 memory_order 来保证数据的可见性和原子性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/3834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在SPringBoot生成验证码

1.引入依赖,这个依赖中包含了生成验证码的工具类 <!--引入hutool --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.9</version></dependency> 2.编写配置类 import cn.hu…

Linux字符设备操作函数

Linux字符设备操作函数是指对字符设备进行打开、关闭、读取、写入、控制等基本操作的函数&#xff0c;它们通过字符设备结构体中的 file_operations 结构体来定义。常用的字符设备操作函数包括&#xff1a; 1、open: 当一个进程试图打开设备文件时&#xff0c;调用这个函数。开…

华润燃气牵手腾讯云 数字技术助力燃气行业高质量发展

7月13日&#xff0c;华润燃气与腾讯云正式签署战略合作协议。双方将充分发挥各自优势&#xff0c;探索AI大模型在燃气行业的深度应用&#xff0c;并深耕分布式计算、连接和客户运营等领域&#xff0c;不断提升燃气民生服务的效率、质量&#xff0c;共同推动行业数字化转型和高质…

ASEMI快恢复二极管MUR20100CTR在电子工程中的应用

编辑-Z 随着电子技术的日益发展&#xff0c;各种电子元件的使用场景与需求也在逐步扩大。今天&#xff0c;我们将聚焦于一款广泛应用于各类电路的二极管——MUR20100CTR&#xff0c;来详细解读其性能特征及应用。 一、MUR20100CTR二极管的主要特性 MUR20100CTR是一款极高性能的…

DataTable数据对比

DataTable数据对比 文章目录 DataTable数据对比前言一、计算DataTable差集结构不同的情况结构相同的情况 二、计算DataTable交集结构不同的情况结构相同的情况 三、计算DataTable的并集合两个DaTable结构相同的情况计算并集 前言 开发中我们经常会出现查询数据库后返回DataTab…

【iOS安全】iphone出现support.apple.com/iphone/restore

解决iphone出现support.apple.com/iphone/restore 解决方法1&#xff1a;使用爱思助手 可能是因为手机进入了恢复模式 手机连接Mac端的爱思助手之后&#xff0c;使用爱思助手的“退出恢复模式” 经测试有效 解决方法2&#xff1a;iphone强制重启 强制重新启动iPhone8或iPhone…

[Java]Set、Map、List常见实现类的特点、使用方法总结

文章目录 1、图谱2、List1、ArrayList1. 特点2. 常见方法 2、LinkedList1、特点2、常见方法 3、Vector1、特点 3、Map1、HashMap1、特点常用方法 2、TreeMap1、特点 3、LinkedHashMap1、特点 4、Set1、HashSet1 、特点2、常用方法 2、LinkedHashSet特点 3、TreeSet1、特点2、使…

Python - Django 框架 - 设置SECRET_KEY

在Django中&#xff0c;SECRET_KEY是一个重要的配置项&#xff0c;用于加密和保护用户数据、会话和其他敏感信息。下面是设置SECRET_KEY的几种常见方法&#xff1a; 1、在settings.py文件中硬编码设置&#xff1a; 打开项目中的settings.py文件&#xff0c;并在其中定义一个字…

SEED实验复现

SEED 项目由雪城大学教授杜文亮于 2002 年启动雪城大学。它由美国总共1万美元资助 美国国家科学基金会。现在&#xff0c;SEED 实验室正在被超过 全球数千个研究所。SEED 代表 &#xff08;SEcurity EDucaton&#xff09;。 https://github.com/seed-labs/seed-labs 该项目使用…

C++牛客WebServer项目学习笔记一

1.Linux系统命令&#xff1a; sudo apt install softname # sudo 管理员权限&#xff1b;apt 安装软件命令&#xff1b;ps -ef | grep ssh # ps 查看进程命令&#xff1b;| 管道符&#xff1b;grep 过滤出&#xff08;过滤出ssh关键词&#xff09;&#xff1b; 3.Ctrl滚动鼠标…

Qt添加第三方字体

最近开发项目时&#xff0c;据说不能用系统自带的微软雅黑字体&#xff0c;于是找一个开源的字体&#xff0c;思源黑体&#xff0c;这个是google和Adobe公司合力开发的可以免费使用。本篇记录一下Qt使用第三方字体的方式。字体从下载之家下载http://www.downza.cn/soft/266042.…

Python爬虫——urllib_微博cookie登陆

cookie登陆适用场景&#xff1a; 适用场景&#xff1a;数据采集的时候&#xff0c;需要绕过登陆&#xff0c;然后进入到某个页面 # 适用场景&#xff1a;数据采集的时候&#xff0c;需要绕过登陆&#xff0c;然后进入到某个页面 import urllib.requesturl https://weibo.cn/7…

selenium

现场打脸&#xff1a;如何使用Selenium批量上传文件&#xff1f; Automa官网 低代码开发&#xff0c;推荐一款Web 端自动化神器&#xff1a;Automa 网页自动化操作工具Automa学习使用记录01 网页自动化操作工具Automa学习使用记录02 - 变量用法 selenium 完整的线程和进程创建…

【解决】Android Studio打包出现not found for signing config ‘externalOverride‘

问题出现场景 之前我的这个项目在另一台电脑上开发&#xff0c;现在迁移到这台计算机上&#xff0c;出现了key报错的问题&#xff0c;网络上有些说需要在XML中进行配置signature相关的内容&#xff0c;这个感觉比较复杂&#xff0c;本文主要介绍一个简单的解决方法&#xff0c;…

SOT封装特点和优势,sot23封装尺寸

SOT封装是一种常用的集成电路封装类型&#xff0c;常见的SOT封装类型包括3引脚&#xff08;如SOT-23&#xff09;、4引脚&#xff08;如SOT-89和SOT-223&#xff09;和6引脚&#xff08;如SOT-363&#xff09;&#xff0c;可以适应不同的电路设计和功能要求。具有以下特点和优势…

机械设计制造及其自动化专业向PLC方向发展的可行性

是的&#xff0c;机械设计制造及其自动化专业往PLC&#xff08;可编程逻辑控制器&#xff09;方向发展是可行的。PLC是一种用于控制和自动化各种机械设备和工业过程的计算机控制系统。它被广泛应用于工业自动化领域&#xff0c;包括制造业、能源行业、交通运输等。 我这里刚好…

UNIX/LINUX fork函数的问题 并不适合共享

起因介绍 一位朋友问我一个关于socket通信的相关问题&#xff0c;其需要解决的问题如下&#xff1a; 需要存在一个服务器进程&#xff0c;服务器进程会进行监听&#xff0c;负责建立与客户端的socket连接&#xff0c;同时可以存在多个客户端进程&#xff0c;客户端进程之间可以…

提示工程师:如何写好Prompt

提示工程由来 提示工程是一门相对较新的学科&#xff0c;用于开发和优化提示以有效地将语言模型 (LM) 用于各种应用程序和研究主题。 研究人员使用提示工程来提高 LLM 在广泛的常见和复杂任务&#xff08;例如问题回答和算术推理&#xff09;上的能力。 开发人员使用提示工程…

JavaWeb(4)——HTML、CSS、JS 快速入门

一、JavaScript 数组 数组筛选&#xff08;查找&#xff0c;将原来数组中的某些数据去除&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content&quo…

接下来讲一讲Vue的数据代理

首先讲一下原生js的数据代理 原生的 Object.defineProperty() let aa wewewlet person {name: "王李斌",age: 12} Object.defineProperty(person, "address", {// value: 14&#xff0c; 给字段设置值//enumerable:true, 设置动态设置的字段为可以遍历/…