如何在 C# 中以原子方式交换 2 个整数? [英] How do I atomically swap 2 ints in C#?

查看:27
本文介绍了如何在 C# 中以原子方式交换 2 个整数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

x86 asm 的 C# 等价物是什么(如果有)xchg 指令?

What (if any) is the C# equivalent of the x86 asm xchg instruction?

使用该命令,哪个 imo 是真正的交换(与 Interlocked.Exchange 不同),我可以简单地以原子方式交换两个整数,这正是我真正想要做的.

With that command, which imo is a genuine exchange (unlike Interlocked.Exchange), I could simply atomically swap two ints, which is what I am really trying to do.

更新:

基于我的建议的示例代码.后缀_V"的变量被修饰为 volatile:

Sample code based upon my suggestion. Variable suffixed "_V" are decorated as volatile:

// PART 3 - process links
// prepare the new Producer
address.ProducerNew.WorkMask_V = 0;
// copy the current LinkMask
address.ProducerNew.LinkMask_V = address.Producer.LinkMask_V;
// has another (any) thread indicated it dropped its message link from this thread?
if (this.routerEmptyMask[address.ID] != 0)
{
  // allow all other bits to remain on (i.e. turn off now defunct links)
  address.ProducerNew.LinkMask_V &= ~this.routerEmptyMask[address.ID];
  // reset
  this.routerEmptyMask[address.ID] = 0;
}
// PART 4 - swap
address.ProducerNew = Interlocked.Exchange<IPC.Producer>(ref address.Producer, address.ProducerNew);
// PART 5 - lazily include the new links, make a working copy
workMask = address.Producer.LinkMask_V |= address.ProducerNew.WorkMask_V;

注意延迟更新.

推荐答案

这里有一个奇怪的想法.我不知道你是如何设置数据结构的.但是,如果您可以将两个 int 值存储在 long 中,那么我认为您可以交换它们以原子方式.

Here's kind of a weird idea. I don't know exactly how you have your data structure set up. But if it's possible you could store your two int values in a long, then I think you could swap them atomically.

例如,假设您按以下方式包装了两个值:

For example, let's say you wrapped your two values in the following manner:

class SwappablePair
{
    long m_pair;

    public SwappablePair(int x, int y)
    {
        m_pair = ((long)x << 32) | (uint)y;
    }

    /// <summary>
    /// Reads the values of X and Y atomically.
    /// </summary>
    public void GetValues(out int x, out int y)
    {
        long current = Interlocked.Read(ref m_pair);

        x = (int)(current >> 32);
        y = (int)(current & 0xffffffff);
    }

    /// <summary>
    /// Sets the values of X and Y atomically.
    /// </summary>
    public void SetValues(int x, int y)
    {
        // If you wanted, you could also take the return value here
        // and set two out int parameters to indicate what the previous
        // values were.
        Interlocked.Exchange(ref m_pair, ((long)x << 32) | (uint)y);
    }
}

然后似乎您可以添加以下 Swap 方法以原子地"产生交换对(实际上,我不知道是否真的说以下是公平的) 原子;它更像是产生与原子交换相同的结果).

Then it seems you could add the following Swap method to result in a swapped pair "atomically" (actually, I don't know if it's fair to really say that the following is atomic; it's more like it produces the same result as an atomic swap).

/// <summary>
/// Swaps the values of X and Y atomically.
/// </summary>
public void Swap()
{
    long orig, swapped;
    do
    {
        orig = Interlocked.Read(ref m_pair);
        swapped = orig << 32 | (uint)(orig >> 32);
    } while (Interlocked.CompareExchange(ref m_pair, swapped, orig) != orig);
}

当然,我很可能错误地实现了这一点.这个想法可能存在缺陷.这只是一个想法.

It is highly possible I've implemented this incorrectly, of course. And there could be a flaw in this idea. It's just an idea.

这篇关于如何在 C# 中以原子方式交换 2 个整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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