将Interlocked.CompareExchange与类一起使用 [英] Using Interlocked.CompareExchange with a class

查看:92
本文介绍了将Interlocked.CompareExchange与类一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

System.Threading.Interlocked.CompareExchange 运算符提供Compare-And-Swap操作的原子(因此是线程安全的)C#实现.

System.Threading.Interlocked.CompareExchange operator provides atomic (thus thread-safe) C# implementation of the Compare-And-Swap operation.

例如 int i = 5;Interlocked.CompareExchange(ref i,10,5); 在此命令之后,int i的值将为10.并且比较和交换也自动进行(单个操作).

For example int i = 5; Interlocked.CompareExchange(ref i, 10, 5); After this command, the int i would have a value = 10. And also the compare and exchange happens atomically (single operation).

当我尝试将其与类实例一起使用时,比较失败并且不交换值.

When I tried using this with a class instance, the compare fails and the values are not exchanged.

   public class X
   {
       public int y;
       public X(int val) { y = val; }
   }

现在,当我这样做

    X a = new X(1);
    X b = new X(1);
    X c = new X(2);
    Interlocked.CompareExchange<X>(ref a, c, b);

比较和交换操作失败.因此,我将类X的Equals和==运算符覆盖为

The compare and Exchange operation fails. So, I overrided the Equals and the == operator for the class X as

    public override bool Equals(object obj) { return y == ((X) obj).y; }

所以,现在我得到 Interlocked.Equals(a,b) true ,但是 CompareExchange 操作仍然失败.

So, now I get Interlocked.Equals(a,b) as true, but the CompareExchange operations still fails.

有什么方法可以做到这一点?我想比较两个类实例,并根据比较结果为其分配一个值.

Is there any method to do this? I want to compare two class instances and assign one of them a value based on the comparision.

推荐答案

否.无法做到.

Interlocked.CompareExchange 基本上直接映射到汇编指令,该指令能够原子比较和交换内存地址的内容.我相信在32位模式下,该指令可以使用64位版本(以及32位和16位版本),在64位模式下,我认为可以使用128位版本.但是,仅此而已.CPU没有基于其特定 Equals 函数的交换.NET类"指令.

Interlocked.CompareExchange basically maps directly to an assembly instruction which is able to atomically compare and swap the contents of a memory address. I believe in 32-bit mode, a 64-bit version of the instruction is available (as well as 32- and 16-bit versions), and in 64-bit mode, I think a 128-bit version is available. But that's all. The CPU doesnt' have a "swap .NET class based on its specific Equals function" instruction.

如果要使用任意相等函数交换任意对象,则必须使用锁或其他同步机制自行完成.

If you want to swap arbitrary objects, using arbitrary equality functions, you have to do it yourself, using locks or other synchronization mechanisms.

Interlocked.CompareExchange有过载.函数可用于对象引用,但由于上述原因,它使用了引用相等.它只是比较引用,然后交换它们.

There is an overload of the Interlocked.CompareExchange function which works on object references, but it uses reference equality for the above reason. It simply compares the references, and then swaps them.

针对您的评论,使用结构不能解决问题.同样,CPU只能原子地比较和交换某些固定大小的值,并且没有抽象数据类型的概念.可以使用引用类型,因为引用本身具有有效的大小,并且可以与CPU的另一个引用进行比较.但是CPU对引用指向的对象一无所知.

In response to your comment, using structs would not solve the problem. Again, the CPU can only atomically compare and swap values of certain fixed sizes, and it has no notion of abstract datatypes. Reference types can be used because the reference itself has a valid size, and can be compared against another reference by the CPU. But the CPU knows nothing about the object that the reference points to.

这篇关于将Interlocked.CompareExchange与类一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆