gpt4 book ai didi

c# - 如何使用内存屏障?安全 Atomicity 操作的方法?

转载 作者:太空狗 更新时间:2023-10-30 01:24:59 26 4
gpt4 key购买 nike

虽然我在学习threading memory barrier (fences) 好像真的不太好理解,在我这里我想让employee 10 threads同时增加一个Int32数:x每次 (x++) 重复 100 次,将得到结果 10 * 100 = 1000。

所以这实际上是一个原子性问题,据我所知,目前有多种方法可以实现这一点 - 仅限于并发方式:

  1. 互锁.增量
  2. 独占锁(lock、monitor、Mutex、Semaphore等)
  3. ReadWriteLockSlim

If there are more better ways please kindly guide me, I tried to use a volatile read/write but failed:

for (int i = 0; i < 10000; i++)
{
Thread.VolatileRead(ref x);
Thread.VolatileWrite(ref x, x + 1);
}

我的调查代码整理如下:

private const int MaxThraedCount = 10;
private Thread[] m_Workers = new Thread[MaxThraedCount];
private volatile int m_Counter = 0;
private Int32 x = 0;

protected void btn_DoWork_Click(object sender, EventArgs e)
{
for (int i = 0; i < MaxThraedCount; i++)
{
m_Workers[i] = new Thread(IncreaseNumber) { Name = "Thread " + (i + 1) };
m_Workers[i].Start();
}
}

void IncreaseNumber()
{
try
{
for (int i = 0; i < 10000; i++)
Interlocked.Increment(ref x);

// Increases Counter and decides whether or not sets the finish signal
m_Counter++;
if (m_Counter == MaxThraedCount)
{
// Print finish information on UI
m_Counter = 0;
}
}
catch (Exception ex)
{
throw;
}
}

我的问题是:如何使用Memory Barrier 来替换Interlocked,因为“All of Interlocked’s methods generate a full fence.”,我尝试如下修改增加循环但失败了,我不明白为什么。 ..

for (int i = 0; i < 10000; i++)
{
Thread.MemoryBarrier();
x++;
Thread.MemoryBarrier();
}

最佳答案

内存屏障只是防止内存操作从屏障的一侧移动到另一侧。你的问题是这样的:

  1. 线程 A 读取 X 的值。
  2. 线程 B 读取 X 的值。
  3. 线程 A 将其读取的值加一。
  4. 线程 B 将其读取的值加一。
  5. 线程 A 写回它计算的值。
  6. 线程 B 写回它计算的值。

糟糕,两个增量只增加了一个。内存屏障不是原子操作,也不是锁。它们只是强制执行顺序,而不是原子性。

不幸的是,x86 架构不提供任何不包含完整栅栏的原子操作。就是这样。从好的方面来说,完整的围栏得到了极大的优化。 (例如,它永远不会锁定任何总线。)

关于c# - 如何使用内存屏障?安全 Atomicity 操作的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7949440/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com