标签: interlocked

Interlocked.Read/Exchange for longs on 64-bit 体系结构

是否Interlocked.Read(ref long)在 64 位架构上进行了“优化”?即如果我正在编写一个可以被两种架构使用的库,我是否应该担心Interlocked.Read在 64 位 CPU 上不必要地使用性能影响?

我想过使用这样的东西,所以我想知道这是否有意义:

    // X64 is a preprocessor constant set for x64 builds  

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static long Read(ref long address)
    {
#if X64
        // atomic on 64-bit processors
        return address;
#else
        // if I got it right, this creates a full memory barrier
        return Interlocked.Read(ref address);
#endif
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void Write(ref long address, long value)
    {
#if X64
        // atomic on 64-bit processors
        address = value;
#else
        // …
Run Code Online (Sandbox Code Playgroud)

c# multithreading interlocked atomicity

4
推荐指数
1
解决办法
646
查看次数

Interlocked.Exchange不能与泛型一起使用?

我正在编写一个通用类,我需要使用Interlocked.

T test1, test2;
Interlocked.Exchange<T>(ref test1, test2);
Run Code Online (Sandbox Code Playgroud)

这不会编译.所以我被迫使用Exchange(对象,对象)而不是MSDN建议不要那样使用它?

c# generics interlocked

3
推荐指数
1
解决办法
388
查看次数

Interlocked.Exchange澄清

我有一些简单(希望)的问题,我一直无法找到答案 -

假设我有多个线程可以访问的对象a,b.

Interlocked.Exchange(ref a, b)
Run Code Online (Sandbox Code Playgroud)

如果'b'不是易变的,这个操作会不会这样处理?即它会从内存中获取此变量的最新值吗?如果是这样,那写入是'原子'吗?据我所知,Interlocked.Exchange的主要目的是使用新写入将原来的'a'值作为原子操作.但我的主要困惑在于'b'实际写入'a'的价值.

我的第二个问题与本文中的引用有关:

http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/

"一个有趣的观点是,C#中的所有写入都是根据此处和此处记录的内存模型进行的,并且也可能是这样实现的.C#语言的ECMA规范实际上定义了一个较弱的模型,其中写入默认情况下不是易失性的".

这是真的?如果是这样,如果不关心'a'的先前值,是否有Interlocked.Exchange的目的?(与我的第一个例子有关).我没有在StackOverflow上看到任何关于每个写入易失性的文章或评论.但是,我知道写入是原子的.

编辑:如果我的第一个问题的答案是"b"不被视为易失性,而我的第二个问题的答案是写入确实是不稳定的,那么跟进就是,什么时候是联锁的.如果我们不这样做,则有用关心'a'的先前价值?

c# multithreading .net-4.0 interlocked

3
推荐指数
1
解决办法
3166
查看次数

Interlocked.Increment vs lock in debug vs release mode

我正在测试我的计算机架构上的行为Interlocked.Incrementlock行为,因为我阅读了本文中的以下几行。

正如用 Interlocked.Increment 重写的那样,该方法应该执行得更快,至少在某些架构上是这样。

使用以下代码,我确信在我的项目中检查锁是值得的。

var watch = new Stopwatch();
var locker = new object();
int counter = 0;

watch.Start();
for (int i = 0; i < 100000000; i++)
{
    lock (locker)
    {
        counter++;
    }
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);

watch.Reset();
counter = 0;

watch.Start();
for (int i = 0; i < 100000000; i++)
{
    Interlocked.Increment(ref counter);
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);
Run Code Online (Sandbox Code Playgroud)

我越来越有近似值稳定的结果2.4S用于锁定和1.2秒的互锁。然而,我惊讶地发现在发布模式下运行此代码仅将 Interlocked 的值提高到大约0.7 秒,并且锁定时间保持不变。这是为什么?在释放模式下锁定不是互锁时如何优化互锁?

c# locking interlocked release-mode debug-mode

3
推荐指数
1
解决办法
448
查看次数

在MSVC中,为什么InterlockedOr和InterlockedAnd生成循环而不是简单的锁定指令?

在MSVC for x64(19.10.25019)上,

    InterlockedOr(&g, 1) 
Run Code Online (Sandbox Code Playgroud)

生成此代码序列:

    prefetchw BYTE PTR ?g@@3JC
    mov     eax, DWORD PTR ?g@@3JC                  ; g
    npad    3
$LL3@f:
    mov     ecx, eax
    or      ecx, 1
    lock cmpxchg DWORD PTR ?g@@3JC, ecx             ; g
    jne     SHORT $LL3@f
Run Code Online (Sandbox Code Playgroud)

我本来期望更简单(和无环):

    mov      eax, 1
    lock or  [?g@@3JC], eax
Run Code Online (Sandbox Code Playgroud)

InterlockedAnd生成类似的代码InterlockedOr.

必须为此指令设置循环似乎非常低效.为什么会生成此代码?

(作为旁注:我使用的全部原因是InterlockedOr对变量进行原子加载 - 我已经知道这InterlockedCompareExchange是做到这一点的方法.我很奇怪没有InterlockedLoad(&x),但我离题了... )

interlocked lock-free visual-c++ data-synchronization

3
推荐指数
1
解决办法
313
查看次数

InterlockedExchange与InterlockedExchangePointer

InterlockedExchange和之间有什么区别InterlockedExchangePointer

if( 0 != InterlockedCompareExchange( ( void** ) &_myVariable
                                   , temp
                                   , 0
                                   ) )
Run Code Online (Sandbox Code Playgroud)

if( 0 != InterlockedCompareExchangePointer( ( void** ) &_myVariable
                                          , temp
                                          , 0
                                          ) )
Run Code Online (Sandbox Code Playgroud)

当量?

我必须将代码移植到VC6,后者不知道这些Interlocked[...]Pointer功能.

编辑:

根据我自己的经验,我知道VC6 非常多,并且没有人会再使用它了.

但是,我不是决策者,对原始问题的回答将受到高度赞赏.

c++ atomic visual-c++-6 interlocked

2
推荐指数
1
解决办法
2349
查看次数

如何在 C# 中检查 Interlocked.Increment 后是否溢出?

调用后检查溢出的正确方法是什么Interlocked.Increment

我有一个 ID 生成器,可以在程序执行期间生成唯一的 ID,目前我测试增量是否返回零。

public static class IdGenerator {
    private static int _counter = 0;
    
    public static uint GetNewId() {
        uint newId = (uint)System.Threading.Interlocked.Increment(ref _counter);
        if (newId == 0) {
             throw new System.Exception("Whoops, ran out of identifiers");
        }
        return newId;
    }
}
Run Code Online (Sandbox Code Playgroud)

鉴于我每次运行生成的 ID 数量相当大,(在异常大的输入上)_counter增量时可能会溢出,并且我想在这种情况下抛出异常(尽早崩溃以简化调试)。

摘自微软的文档

location此方法通过包装: if = Int32.MaxValue, location + 1=来处理溢出情况Int32.MinValue。没有抛出异常。

c# integer-overflow interlocked interlocked-increment

2
推荐指数
1
解决办法
2977
查看次数

C#互锁功能作为锁机制?

当我读到关于ReaderWriterLockSlim锁机制的时候,有人提出Interlock函数可用于更精细的锁定

另外,我在这里找到 Marc的另一个答案:

...写入对克隆副本进行更改,然后使用Interlocked.CompareExchange交换引用(如果另一个线程在临时中突变了引用,则重新应用它们的更改).

那么,目前,所有我知道的Interlocked对象,是它使用(在多线程环境)做原子additions,compare,compareExchange操作.(我知道如何使用它)

但是(这是我的问题) -

我怎样才能将它用作?(示例代码将非常感谢)

编辑

为简单起见,我正在粘贴此代码(这不是线程安全的 - 如果 Go同时由两个线程调用,则可能会出现一个被零除错误):

class ThreadUnsafe
 {
   static int _val1 = 1, _val2 = 1;

   static void Go()
       {
        if (_val2 != 0) Console.WriteLine (_val1 / _val2);
        _val2 = 0;
       }
}
Run Code Online (Sandbox Code Playgroud)

如何使用互锁来替换锁(这会解决问题)?

c# multithreading locking interlocked

2
推荐指数
1
解决办法
1013
查看次数

锁 vs Interlocked.Exchange

我有一个应用程序,它不断(+-100 毫秒)从 PLC 读取订单,然后将它们放入一个模型中,然后由多个客户端读取。为此,我使用 lock 语句。

订单阅读线程:

lock (model) {
//update object
}
Run Code Online (Sandbox Code Playgroud)

客户阅读:

lock (model) {
//serialize object to json string
}
send over tcp stream to client.
Run Code Online (Sandbox Code Playgroud)

但我也可以用于更新:

Interlocked.ExChange(oldObj, newObj)
Run Code Online (Sandbox Code Playgroud)

我不希望我的客户必须等待订单读取线程中发生的锁定。而且我绝对不希望客户阻止我的订单阅读线程。

我最好使用 Interlocked 吗?

感谢您的建议!

c# multithreading locking interlocked task

2
推荐指数
1
解决办法
2495
查看次数

什么是C#`Interlocked.Exchange(Object,Object):Object`的Java等价物?

C#的Java等价物是Interlocked.Exchange(Object, Object) : Object什么?Java中是否有一种方法可以在没有锁定的单个原子步骤中执行以下操作:1)在本地存储变量的引用2)设置对同一变量的另一个引用?

c# java locking interlocked

2
推荐指数
1
解决办法
776
查看次数