如何在 C# 中以原子方式交换 2 个整数? [英] How do I atomically swap 2 ints in C#?
问题描述
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屋!