c#多线程之Interlocked

方法

Interlocked.Increment(ref value) 数值加一(原子性操作)

Interlocked.Decrement(ref value) 数值减一(原子性操作)

Interlocked.Exchange(ref value1, value2) 交换:把值2赋给值1;返回新值

Interlocked.CompareExchange(ref value1, value2, value3) 实现比较和交换两种功能:值1和值3比较,如果相同,把值2给值1,不相同则不作任何操作;返回原值(多用于判断条件)

Interlocked.MemoryBarrier :按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行 MemoryBarrier() 调用之后的内存存取,再执行 MemoryBarrier() 调用之前的内存存取的方式。Thread.MemoryBarrier 就是包装了它。

个人补充:值刷新当前执行线程的cpu上的store buffer和Invalidate queue都运行完成了.

Interlocked.MemoryBarrierProcessWide:内部执行FlushProcessWriteBuffers函数()。该函数功能刷新正在运行当前进程所有线程的每个处理器的写入队列(store buffer)。该函数为属于当前进程关联一部分的所有处理器生成一个处理器间中断 (IPI)。它保证了在一个处理器上对另一个处理器执行的写入操作的可见性。

个人补充:将当前进程下所有线程所在的cpu上的store buffer和Invalidate queue都运行完成了,所以非常耗费时间 。

using System;
using System.Threading;
using System.Threading.Tasks;

namespace MemoryBarriers
{
    class Program
    {
        static volatile int x, y, a, b;
        static void Main()
        {
            while (true)
            {
                var t1 = Task.Run(Test1);
                var t2 = Task.Run(Test2);
                
                Task.WaitAll(t1, t2);
                if (a == 0 && b == 0)
                {
                    Console.WriteLine("{0}, {1}", a, b);
                }
              
                x = y = a = b = 0;
            }
        }

        static void Test1()
        {
            x = 1;
 
           //方案一 Interlocked.MemoryBarrier();
           //方案二 Interlocked.MemoryBarrierProcessWide();

            a = y;
        }

        static void Test2()
        {
             
            y = 1;

            //方案一 Interlocked.MemoryBarrier();
            b = x;
          
        }
    }
}

猜你喜欢

转载自blog.csdn.net/a_codecat/article/details/128450104