繁体   English   中英

Interlocked.Exchange 和 Interlocked.Exchange 全局结构支持的线程安全通用替代方案

[英]Thread safe generic alternative to Interlocked.Exchange and Interlocked.Exchange global struct support

`Interlocked.MemoryBarrier' 是否为泛型类型支持提供了足够的防护,如以下示例中实现的那样?

// Out of scope Interlocked.* methods omitted

    public static T CompareExchange<T>(ref T location, T value, T comparand)
        where T : unmanaged
    {
        Interlocked.MemoryBarrier();
        if (Unsafe.AreSame(ref location, ref comparand))
            return Exchange(ref location, value);
        return location;
    }

    public static T Exchange<T>(ref T location, T value)
        where T : unmanaged
    {
        Interlocked.MemoryBarrier();
        location = value;
        Interlocked.MemoryBarrier();
        return location;
    }

在您的实现中,“Unsafe.AreSame”简单地检查对相同 memory 位置的引用。 它并没有像您的意图那样比较结构是否相等(否则只需将内置的泛型重载用于引用类型)。

关于 Interlocked.MemoryBarrier(),它不提供跨线程的排序保证 - 仅阻止某些指令优化。 在您的示例中,对 Exchange 的此实现的两个并发调用可能会返回相同的初始值,这是不正确的。

为了实现原子性,您限制为最大 8 字节的结构。 以下将在 8 字节约束下实现您的 object:


public static T CompareExchange<T>(ref T location, T value, T comparand)
    where T : unmanaged =>
Unsafe.SizeOf<T>() switch
{
    4 => Unsafe.As<int, T>(ref Unsafe.AsRef(Interlocked.CompareExchange(ref Unsafe.As<T, int>(ref location), Unsafe.As<T, int>(ref value), Unsafe.As<T, int>(ref comparand)))),
    8 => Unsafe.As<long, T>(ref Unsafe.AsRef(Interlocked.CompareExchange(ref Unsafe.As<T, long>(ref location), Unsafe.As<T, long>(ref value), Unsafe.As<T, long>(ref comparand)))),
    _ => throw new NotSupportedException("Type exceeds 8-bytes")
};

public static T Exchange<T>(ref T location, T value)
    where T : unmanaged =>
Unsafe.SizeOf<T>() switch
{
    4 => Unsafe.As<int, T>(ref Unsafe.AsRef(Interlocked.Exchange(ref Unsafe.As<T, int>(ref location), Unsafe.As<T, int>(ref value)))),
    8 => Unsafe.As<long, T>(ref Unsafe.AsRef(Interlocked.Exchange(ref Unsafe.As<T, long>(ref location), Unsafe.As<T, long>(ref value)))),
    _ => throw new NotSupportedException("Type exceeds 8-bytes")
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM