C# Interlocked 原子操作

2024-06-08 1154阅读

目录

注解

方法

适用于

案例

 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 位无符号整数是否相等,如果相等,则替换第一个值。

(T, T, T)">CompareExchange(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 位无符号整数设置为指定的值并返回原始值。

(T, T)">Exchange(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  

执行结果

C# Interlocked 原子操作

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]