标签: interlocked

带枚举的Interlocked.CompareExchange

我正在尝试使用Interlocked.CompareExchange这个枚举:

public enum State {
    Idle,
    Running,
    //...
}
Run Code Online (Sandbox Code Playgroud)

以下代码无法编译,但这就是我想要做的:

if (Interlocked.CompareExchange(ref state, State.Running, State.Idle) != State.Idle) {
    throw new InvalidOperationException("Unable to run - not idle");
}
Run Code Online (Sandbox Code Playgroud)

当然我可以使用int而不是枚举并使用属性:

private int state = (int)State.Idle;
public State { get { return (State)state; } }
Run Code Online (Sandbox Code Playgroud)

然后将枚举转换为int:

if (Interlocked.CompareExchange(ref state, (int)State.Running, (int)State.Idle) !=  (int)State.Idle) {
    throw new InvalidOperationException("Unable to run - not idle");
}
Run Code Online (Sandbox Code Playgroud)

但有没有更好的方法来做到这一点?

c# interlocked

17
推荐指数
4
解决办法
2577
查看次数

C#从根本上说不便携?

我一直在使用C#,并且最近开始致力于为我的侧面项目添加并行性.因此,根据微软的说法,读取和写入int甚至浮点数都是原子的

我确信这些原子性要求在x86架构上运行得很好.但是,在ARM(可能没有硬件浮点支持)等体系结构上,似乎这些保证很难.

问题只是因为'int'总是32位而变得更加重要.有许多嵌入式设备无法自动执行32位写入.

这似乎是C#中的一个根本错误.保证这些数据类型的原子性不能轻松完成.

这些原子性保证如何在没有FPU或32位写入的架构上实现?

.net c# parallel-processing interlocked atomicity

16
推荐指数
4
解决办法
2944
查看次数

什么是Java相当于.Net的Interlocked类?

如何在Java中原子地和线程安全地修改int?

原子增量,测试和设置等......?

java concurrency multithreading interlocked

15
推荐指数
1
解决办法
7441
查看次数

内存屏障vs内存对内存的影响缓存一致性时序

简化问题:

与内存屏障相比,互锁操作引起的内存缓存一致性(或"刷新")的时间是否存在差异?让我们在C#中考虑 - 任何互锁操作与Thread.MemoryBarrier().我相信存在差异.

背景:

我读了很少关于内存障碍的信息 - 所有对预防特定类型的内存交互指令重新排序的影响,但是我找不到关于它们是否应该立即刷新读/写队列的一致信息.

实际上我发现很少有消息来源提到不能保证操作的即时性(只保证特定的重新排序是有保证的).例如

维基百科:"但是,要明确的是,这并不意味着任何操作都会在屏障完成时完成;只有完成操作的订购(当它们完成时)才能得到保证"

Freebsd.org(障碍是硬件特定的,所以我猜一个特定的操作系统并不重要):"内存屏障只是确定内存操作的相对顺序;它们不保证内存操作的时间"

另一方面,Interlocked操作 - 从他们的定义 - 导致立即刷新所有内存缓冲区以保证更新的最新值更新导致内存子系统用值锁定整个缓存行,以防止从任何访问(包括读取)其他CPU /核心,直到操作完成.

我纠正还是错了?

免责声明:

这是我在这里的原始问题的演变.在.NET中的可变新鲜度保证(易失性与易失性读取)

EDIT1: 修复了关于Interlocked操作的声明 - 内联文本.

编辑2: 完全删除演示代码+它的讨论(因为一些人抱怨太多的信息)

c# multithreading interlocked memory-barriers

14
推荐指数
2
解决办法
1414
查看次数

将Interlocked.CompareExchange与类一起使用

System.Threading.Interlocked.CompareExchange operator提供了Compare-And-Swap操作的原子(因此是线程安全的)C#实现.

例如,int i = 5; Interlocked.CompareExchange(ref i, 10, 5);在此命令之后,int i将具有值= 10.并且比较和交换以原子方式发生(单个操作).

当我尝试将其与类实例一起使用时,比较失败并且不交换值.

   public class X
   {
       public int y;
       public X(int val) { y = val; }
   }
Run Code Online (Sandbox Code Playgroud)

现在当我这样做

    X a = new X(1);
    X b = new X(1);
    X c = new X(2);
    Interlocked.CompareExchange<X>(ref a, c, b);
Run Code Online (Sandbox Code Playgroud)

比较和Exchange操作失败.所以,我将X类的Equals和==运算符重写为

    public override bool Equals(object obj) { return y == ((X) obj).y; }
Run Code Online (Sandbox Code Playgroud)

所以,现在我得到Interlocked.Equals(a,b)true,但CompareExchange操作仍然失败.

有没有办法做到这一点?我想比较两个类实例,并根据比较为其中一个指定一个值.

.net c# multithreading interlocked

12
推荐指数
3
解决办法
9450
查看次数

Interlocked用于增加/模仿布尔值,这样安全吗?

我只是想知道这个代码是否是一个开发人员(后来已经离开)是好的,我想他想避免锁定.这与仅仅使用直接锁之间有性能差异吗?

    private long m_LayoutSuspended = 0;
    public void SuspendLayout()
    {
        Interlocked.Exchange(ref m_LayoutSuspended, 1);
    }

    public void ResumeLayout()
    {
        Interlocked.Exchange(ref m_LayoutSuspended, 0);
    }

    public bool IsLayoutSuspended
    {
        get { return Interlocked.Read(ref m_LayoutSuspended) != 1; }
    }
Run Code Online (Sandbox Code Playgroud)

我认为锁定这样的东西会更容易吗?它确实会被多个线程使用,因此决定使用锁定/互锁的原因.

c# multithreading interlocked

11
推荐指数
2
解决办法
8251
查看次数

为什么Interlocked.Increment在Parallel.ForEach循环中给出了错误的结果?

我有一个迁移工作,我需要在完成后验证目标数据.为了通知管理员验证成功/失败,我使用一个计数器来比较Database1中表Foo的行数和Database2中表Foo的行数.

Database2中的每一行都根据Database1中的相应行进行验证.为了加快这个过程,我使用了一个Parallel.ForEach循环.

我最初的问题是计数总是与我的预期不同.我后来发现+=-=操作不是线程安全的(不是原子的).为了解决这个问题,我更新了用于Interlocked.Increment计数器变量的代码.此代码打印的计数更接近实际计数,但是,每次执行时它似乎都不同,并且它不会给出我期望的结果:

Private countObjects As Integer

Private Sub MyMainFunction()
    Dim objects As List(Of MyObject)

    'Query with Dapper, unrelevant to the problem.
    Using connection As New System.Data.SqlClient.SqlConnection("aConnectionString")
        objects = connection.Query("SELECT * FROM Foo") 'Returns around 81000 rows.
    End Using

    Parallel.ForEach(objects, Sub(u) MyParallelFunction(u))

    Console.WriteLine(String.Format("Count : {0}", countObjects)) 'Prints "Count : 80035" or another incorrect count, which seems to differ on each execution of MyMainFunction.
End Sub

Private Sub MyParallelFunction(obj As MyObject)
    Interlocked.Increment(countObjects) 'Breakpoint …
Run Code Online (Sandbox Code Playgroud)

.net c# vb.net interlocked task-parallel-library

10
推荐指数
1
解决办法
863
查看次数

C#代码优化导致Interlocked.Exchange()出现问题

我有一些代码令人沮丧的问题,不知道为什么会出现这个问题.

//
// .NET FRAMEWORK v4.6.2 Console App

static void Main( string[] args )
{
    var list = new List<string>{ "aa", "bbb", "cccccc", "dddddddd", "eeeeeeeeeeeeeeee", "fffff", "gg" };

    foreach( var item in list )
    {
        Progress( item );
    }
}

private static int _cursorLeft = -1;
private static int _cursorTop = -1;
public static void Progress( string value = null )
{
    lock( Console.Out )
    {
        if( !string.IsNullOrEmpty( value ) )
        {
            Console.Write( value );
            var left = Console.CursorLeft;
            var …
Run Code Online (Sandbox Code Playgroud)

c# optimization release interlocked

10
推荐指数
1
解决办法
327
查看次数

InterlockedIncrement用法

在阅读InterlockedIncrement函数时,我看到了传递的变量必须在32位边界上对齐的注释.通常我见过使用InterlockedIncrement的代码,如下所示:

class A
{
 public:
   A();
   void f();

 private:
  volatile long m_count;
};

A::A() : m_count(0)
{
}

void A::f()
{
  ::InterlockedIncrement(&m_count);
}
Run Code Online (Sandbox Code Playgroud)

以上代码在多处理器系统中是否正常工作,还是应该更加关注?

c++ winapi multithreading multicore interlocked

9
推荐指数
1
解决办法
1万
查看次数

当Interlocked类可用时,为什么在.NET中使用SyncLocks进行简单操作?

我已经在VB.NET中做了一段时间的简单多线程,并刚刚进入我的第一个大型多线程项目.我总是使用Synclock声明完成所有事情,因为我认为没有更好的方法.

我刚刚了解了这个Interlocked类 - 它看起来好像这一切:

Private SomeInt as Integer
Private SomeInt_LockObject as New Object

Public Sub IntrementSomeInt
    Synclock SomeInt_LockObject
        SomeInt += 1
    End Synclock
End Sub
Run Code Online (Sandbox Code Playgroud)

可以用单个语句替换:

Interlocked.Increment(SomeInt)
Run Code Online (Sandbox Code Playgroud)

这会在内部处理所有锁定并修改数字.这比为简单操作编写自己的锁要简单得多(更长时间运行或更复杂的操作显然仍然需要自己的锁定).

当我可以使用这些Interlocked方法完成同样的事情时,我是否有理由使用专用锁定对象来进行自己的锁定?

.net multithreading locking interlocked synclock

9
推荐指数
2
解决办法
8336
查看次数