C# Interlocked 原子操作

目录

注解

方法

适用于

案例

 1:Add 对两个整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成

2:Exchange  Exchange(UInt32, UInt32)  以原子操作的形式,将 32 位无符号整数设置为指定的值并返回原始值。


参考文档:Interlocked 类 (System.Threading) | Microsoft Learn

我对Interlocked原子操作的理解是:如同一桌人喝一碗汤,汤碗里面有一个公用的勺子,不能多个人同时使这把公用的勺子舀汤,  当有人想喝汤时(或者服务员想要加汤时),就得先拿到勺子,其他人就没法喝汤(或者添汤)。只有喝汤的人(添汤的人)用完勺子放回汤碗后,其他人才能继续使用勺子喝汤(添汤)。

注解

此类的方法可帮助防止在以下情况下发生的错误:在以下情况下发生:计划程序在以下情况下切换上下文:当线程正在更新可被其他线程访问的变量时,或当两个线程同时在不同的处理器上执行时。 此类的成员不会引发异常。

Increment和 Decrement 方法递增或递减变量,并在单个操作中存储生成的值。 在大多数计算机上,递增变量不是原子操作,需要执行以下步骤:

  1. 将实例变量中的值加载到寄存器中。

  2. 递增或减小值。

  3. 将值存储在实例变量中。

如果不使用 Increment 和,则在 Decrement 执行前两个步骤后,线程可以被抢占。 然后,另一个线程可以执行所有三个步骤。 当第一个线程继续执行时,它将覆盖实例变量中的值,并且由第二个线程执行的增量或减量的影响将丢失。

Add方法以原子方式将整数值添加到整数变量中,并返回变量的新值。

Exchange方法以原子方式交换指定变量的值。 CompareExchange方法组合了两个操作:比较两个值,并根据比较结果将第三个值存储在一个变量中。 比较和交换操作以原子操作的方式执行。

确保对共享变量的任何写入或读取访问都是原子的。 否则,数据可能已损坏,或者加载的值可能不正确。

方法

Add(Int32, Int32)

对两个 32 位整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。

Add(Int64, Int64)

对两个 64 位整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。

Add(UInt32, UInt32)

对两个 32 位无符号整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。

Add(UInt64, UInt64)

对两个 64 位无符号整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。

And(Int32, Int32)

对两个 32 位带符号整数进行按位“与”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

And(Int64, Int64)

对两个 64 位带符号整数进行按位“与”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

And(UInt32, UInt32)

对两个 32 位无符号整数进行按位“与”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

And(UInt64, UInt64)

对两个 64 位无符号整数进行按位“与”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

CompareExchange(Double, Double, Double)

比较两个双精度浮点数是否相等,如果相等,则替换第一个值。

CompareExchange(Int32, Int32, Int32)

比较两个 32 位有符号整数是否相等,如果相等,则替换第一个值。

CompareExchange(Int64, Int64, Int64)

比较两个 64 位有符号整数是否相等,如果相等,则替换第一个值。

CompareExchange(IntPtr, IntPtr, IntPtr)

比较两个平台特定的句柄或指针是否相等,如果相等,则替换第一个。

CompareExchange(Object, Object, Object)

比较两个对象是否引用相等,如果相等,则替换第一个对象。

CompareExchange(Single, Single, Single)

比较两个单精度浮点数是否相等,如果相等,则替换第一个值。

CompareExchange(UInt32, UInt32, UInt32)

比较两个 32 位无符号整数是否相等,如果相等,则替换第一个值。

CompareExchange(UInt64, UInt64, UInt64)

比较两个 64 位无符号整数是否相等,如果相等,则替换第一个值。

CompareExchange<T>(T, T, T)

比较指定的引用类型 T 的两个实例是否引用相等,如果相等,则替换第一个。

Decrement(Int32)

以原子操作的形式递减指定变量的值并存储结果。

Decrement(Int64)

以原子操作的形式递减指定变量的值并存储结果。

Decrement(UInt32)

以原子操作的形式递减指定变量的值并存储结果。

Decrement(UInt64)

以原子操作的形式递减指定变量的值并存储结果。

Exchange(Double, Double)

以原子操作的形式,将双精度浮点数设置为指定的值并返回原始值。

Exchange(Int32, Int32)

以原子操作的形式,将 32 位有符号整数设置为指定的值并返回原始值。

Exchange(Int64, Int64)

以原子操作的形式,将 64 位有符号整数设置为指定的值并返回原始值。

Exchange(IntPtr, IntPtr)

以原子操作的形式,将平台特定的句柄或指针设置为指定的值并返回原始值。

Exchange(Object, Object)

以原子操作的形式,将对象设置为指定的值并返回对原始对象的引用。

Exchange(Single, Single)

以原子操作的形式,将单精度浮点数设置为指定的值并返回原始值。

Exchange(UInt32, UInt32)

以原子操作的形式,将 32 位无符号整数设置为指定的值并返回原始值。

Exchange(UInt64, UInt64)

以原子操作的形式,将 64 位无符号整数设置为指定的值并返回原始值。

Exchange<T>(T, T)

以原子操作的形式,将指定类型 T 的变量设置为指定的值并返回原始值。

Increment(Int32)

以原子操作的形式递增指定变量的值并存储结果。

Increment(Int64)

以原子操作的形式递增指定变量的值并存储结果。

Increment(UInt32)

以原子操作的形式递增指定变量的值并存储结果。

Increment(UInt64)

以原子操作的形式递增指定变量的值并存储结果。

MemoryBarrier()

按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行 MemoryBarrier() 调用之后的内存存取,再执行 MemoryBarrier() 调用之前的内存存取的方式。

MemoryBarrierProcessWide()

提供覆盖整个过程的内存屏障,确保来自任何 CPU 的读写都不能越过该屏障。

Or(Int32, Int32)

对两个 32 位带符号整数进行按位“或”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

Or(Int64, Int64)

对两个 64 位带符号整数进行按位“或”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

Or(UInt32, UInt32)

对两个 32 位无符号整数进行按位“或”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

Or(UInt64, UInt64)

对两个 64 位无符号整数进行按位“或”运算,并用结果替换第一个整数,上述操作作为一个原子操作完成。

Read(Int64)

返回一个以原子操作形式加载的 64 位值。

Read(UInt64)

返回一个以原子操作形式加载的 64 位无符号值。

适用于

产品Versions
.NET5.0
.NET Core1.0, 1.1, 2.0, 2.1, 2.2, 3.0, 3.1
.NET Framework1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 2.0, 2.1
UWP10.0
Xamarin.Android7.1
Xamarin.iOS10.8
Xamarin.Mac3.0

案例

1:Add 

对两个整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成

2:Exchange  

以原子操作的形式,将设置为指定的值并返回原始值(或者对象)。

 public class InterlockedExchange
    {
        //0 资源未被使用, 1 资源被占用.
        private static int usingResource = 0;
        //每个线程执行次数
        private const int numThreadIterations = 5;
        //线程数
        private const int numThreads = 10;

        public static void Main1()
        {
            Thread myThread;
            Random rnd = new Random();

            for (int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format($"Thread{i + 1}");

                //在开始下一个线程之前随机等待一段时间。
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("主线程已执行完");
            Console.ResetColor();
        }

        private static void MyThreadProc()
        {
            while(true)
            {
                //如果任务 拿到资源执行
                if (UseResource()) break;

                //等待1秒再执行
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if (0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine($"{Thread.CurrentThread.Name} 获得资源");

                //这里放 用于访问非线程安全的资源代码。

                //模仿 执行的任务,暂停500毫秒
                Thread.Sleep(500);

                Console.WriteLine($"{Thread.CurrentThread.Name} 释放资源");

                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine($"   {Thread.CurrentThread.Name} 拿资源时,被拒绝");
                return false;
            }
        }
    }

执行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

存储设备有哪些?属于私有云平台吗?怎么理解?

数字化的今天&#xff0c;数据已经成为了企业最重要最宝贵的资产了。为了保障数据的安全、可靠和高效利用&#xff0c;存储设备和云计算技术应运而生。今天我们大家就来聊聊存储设备有哪些&#xff1f;属于私有云平台吗&#xff1f;怎么理解&#xff1f; 存储设备有哪些&…

thinkadmin发邮件功能如何设置?怎么使用?

thinkadmin发邮件有哪些注意事项&#xff1f;支持哪些邮件服务&#xff1f; 在使用thinkadmin框架进行开发时&#xff0c;发邮件功能的设置是一个常见的需求。通过合理配置和简单的编程&#xff0c;我们可以轻松地在thinkadmin中集成邮件发送功能。AokSend将详细介绍如何设置t…

动态规划9:LCR 099. 最小路径和

动态规划解题步骤&#xff1a; 1.确定状态表示&#xff1a;dp[i]是什么 2.确定状态转移方程&#xff1a;dp[i]等于什么 3.初始化&#xff1a;确保状态转移方程不越界 4.确定填表顺序&#xff1a;根据状态转移方程即可确定填表顺序 5.确定返回值 题目链接&#xff1a;LCR …

在VS Code中操作MySQL数据库

创建MySQL连接 操作前需要先启动MySQL数据库&#xff0c;个别情况下需要以管理员身份打开cmd&#xff0c;在cmd中输入&#xff1a; net start mysql 我的MySQL数据库服务名为mysql84&#xff0c;需要填写自己的mysql服务名称。 随后在VS Code中下载插件 Prettier SQL VSCode …

新手必看!场外期权交易的六大注意事项

场外期权交易的六大注意事项 对于初涉金融市场的投资者来说&#xff0c;场外期权交易无疑是一个既具吸引力又充满挑战的领域。为确保您在交易中能够稳健获利&#xff0c;以下六大注意事项值得每位新手仔细研读。 文章来源/&#xff1a;财智财经 一、深入理解期权基本概念 场…

海思SS928(SD3403)部署YOLOv5-YOLOv7步骤详解

1. YOLO模型资料 本文档内容以yolov5-7.0工程、yolov5s模型为例。 a. 模型结构 详细的模型结构可以利用netron工具打开.pt或.onnx模型查看。 b. 模型参数即验证结果 其中,YOLOv5n、YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x为五种类型的预训练模型,其包含的检测类别相…

数据中心运维如何使用布线管理软件

1. 什么是可视化布线管理软件 1.1 数据中心布线管理软件部署在本地服务器&#xff0c;通过数据导入将现有的数据中心布线系统的设备信息、线缆连接关系等导入到管理软件中形成数据库&#xff1b; 1.2 布线管理软件提供了实时可视化的管理界面&#xff0c;从园区到建筑到楼…

LabVIEW与Simulink的通信及调用方式

LabVIEW和Simulink可以通过多种方式进行通信和集成&#xff0c;实现数据交互和功能调用。常见的通信方式包括TCP/IP、UDP、共享内存等&#xff0c;此外还可以利用MATLAB Script Node和S-Function等直接调用对方的功能。这些方法使得LabVIEW和Simulink能够协同工作&#xff0c;充…

AI-知识库搭建(一)腾讯云向量数据库使用

一、AI知识库 将已知的问答知识&#xff0c;问题和答案转变成向量存储在向量数据库&#xff0c;在查找答案时&#xff0c;输入问题&#xff0c;将问题向量化&#xff0c;匹配向量库的问题&#xff0c;将向量相似度最高的问题筛选出来&#xff0c;将答案提交。 二、腾讯云向量数…

龙讯旷腾PWmat团队研发的开源机器学习力场PWMLFF升级,新增高效训练NEP模型

近几年来&#xff0c;一种结合了物理学、高性能并行计算和机器学习算法的新的科研范式——AI for science迅速崛起&#xff0c;并为解决精度与尺度无法并存的问题带来了曙光。基于机器学习力场&#xff08;machine learning force field, MLFF&#xff09;的分子动力学&#xf…

Vue2自定义拖拽指令-元素拖拽

Vue2自定义拖拽指令-元素拖拽-参数传递 v-canDraghtml部分/src/directive/canDrag/index.js然后注册到vue实例上就OK了 v-canDrag html部分 <template><div class"drag-container"><div class"drag-div" v-canDrag"{callback:callbac…

新能源集成灶怎么样?不需要燃料就能生火,是真的吗?

在当今的厨房电器领域&#xff0c;集成灶的出现引起了不少网友的广泛关注。这不&#xff0c;就在刚刚人民日报发布的一篇名为《中国新能源产业发展是全球性贡献和机遇》报道中提到&#xff1a;中国新能源产品销量突破万亿大关&#xff0c;中国新能源技术全球领先。从这样一份亮…

1501 - JUC高并发

须知少许凌云志&#xff0c;曾许人间第一流 看的是尚硅谷的视频做的学习总结&#xff0c;感恩老师&#xff0c;下面是视频的地址 传送门https://www.bilibili.com/video/BV1Kw411Z7dF 0.思维导图 1.JUC简介 1.1 什么是JUC JUC&#xff0c; java.util.concurrent工具包的简称…

433/315无线门铃解决方案,功耗超低,通信距离可达200米

无线门铃是一种常见的智能电子设备&#xff0c;提供了方便&#xff0c;安全的门铃解决方案&#xff0c;适用于各种住宅和商业环境。芯岭技术的无线门铃方案可适用于普通的433/315无线门铃应用&#xff0c;支持不同的语音选择&#xff0c;支持交流和直流应用&#xff0c;支持不同…

Python——泰坦尼克号数据分析

目录 🧾1.数据集(部分数据) ✏️ 2、导入数据集与必要模块 ⌨️ 3.数据预处理 1️⃣ isnull函数查看有无缺失值 2️⃣fillna函数填充缺失值 📍 Age字段使用平均值填充缺失值 📍 Embarked字段填充缺失值 3️⃣ 删除缺失值较多的字段 📊 4.数据可视化 1️⃣ di…

每日一练 2024.6.7

给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作&#xff0c;在每一步操作中&#xff0c;你可以从 s 中删除 任一个 "AB" 或 "CD" 子字符串。 通过执行操作&#xff0c;删除所有 "AB" 和 "CD" 子串&#x…

【面试八股总结】死锁:产生条件、预防死锁、处理死锁、避免死锁

一、什么是死锁&#xff1f; 死锁是指两个&#xff08;或多个&#xff09;线程互相等待对方数据的过程&#xff0c;死锁的产生导致程序卡死&#xff0c;不解锁程序将永远⽆法进⾏下 去 二、死锁产生条件 死锁只有同时满足以下四个条件才会发生&#xff1a;互斥条件&#xff1b…

笔记-2024视频会议软件技术选型方案

一、背景 视频会议系统是一种现代化的办公系统&#xff0c;它可以使不同会场的实时现场场景和语音互连起来&#xff0c;同时向与会者提供分享听觉和视觉的空间&#xff0c;使各与会方有“面对面”交谈的感觉。随着社会的发展&#xff0c;视频会议的应用越来越广泛&#xff0c;…

【数据分析基础】实验四 matplotlib数据可视化处理

一&#xff0e;实验目的 掌握扩展库matplotlib及其依赖库的安装。了解matplotlib的绘图一般过程。熟练掌握折线图、散点图、柱状图、饼状图、雷达图的绘制与常用属性的设置。掌握绘图区域的切分、绘制不同子图的方法。熟悉坐标轴、图像标题、图例等对象的属性设置操作。 二、实…

新品!和芯星通全系统全频高精度板卡UB9A0首发

6月6日&#xff0c;和芯星通发布了UB9A0全系统全频高精度GNSS板卡&#xff0c;主要应用于CORS站、便携基站、GNSS全球监测跟踪站等。延续了上一代产品高质量原始观测量的特点&#xff0c;UB9A0在性能和稳定性方面均表现出众。 UB9A0基于射频基带及高精度算法一体化的GNSS SoC芯…