Interlocked Interlocked Interlocked Interlocked Class

定義

為多重執行緒共用的變數提供不可部分完成的作業 (Atomic Operation)。Provides atomic operations for variables that are shared by multiple threads.

public ref class Interlocked abstract sealed
public static class Interlocked
type Interlocked = class
Public Class Interlocked
繼承
InterlockedInterlockedInterlockedInterlocked

範例

下列程式碼範例會示範具備執行緒安全資源的鎖定機制。The following code example shows a thread-safe resource locking mechanism.

using namespace System;
using namespace System::Threading;

const int numThreads = 10;
const int numThreadIterations = 5;
ref class MyInterlockedExchangeExampleClass
{
public:
   static void MyThreadProc()
   {
      for ( int i = 0; i < numThreadIterations; i++ )
      {
         UseResource();
         
         //Wait 1 second before next attempt.
         Thread::Sleep( 1000 );

      }
   }


private:
   //A simple method that denies reentrancy.
   static bool UseResource()
   {
      
      //0 indicates that the method is not in use.
      if ( 0 == Interlocked::Exchange( usingResource, 1 ) )
      {
         Console::WriteLine( " {0} acquired the lock", Thread::CurrentThread->Name );
         
         //Code to access a resource that is not thread safe would go here.
         //Simulate some work
         Thread::Sleep( 500 );
         Console::WriteLine( " {0} exiting lock", Thread::CurrentThread->Name );
         
         //Release the lock
         Interlocked::Exchange( usingResource, 0 );
         return true;
      }
      else
      {
         Console::WriteLine( " {0} was denied the lock", Thread::CurrentThread->Name );
         return false;
      }
   }


   //0 for false, 1 for true.
   static int usingResource;
};

int main()
{
   Thread^ myThread;
   Random^ rnd = gcnew Random;
   for ( int i = 0; i < numThreads; i++ )
   {
      myThread = gcnew Thread( gcnew ThreadStart( MyInterlockedExchangeExampleClass::MyThreadProc ) );
      myThread->Name = String::Format( "Thread {0}", i + 1 );
      
      //Wait a random amount of time before starting next thread.
      Thread::Sleep( rnd->Next( 0, 1000 ) );
      myThread->Start();

   }
}

using System;
using System.Threading;

namespace InterlockedExchange_Example
{
    class MyInterlockedExchangeExampleClass
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;
        private const int numThreads = 10;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for(int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);
            
                //Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }
        }

        private static void MyThreadProc()
        {
            for(int i = 0; i < numThreadIterations; i++)
            {
                UseResource();
            
                //Wait 1 second before next attempt.
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if(0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
            
                //Code to access a resource that is not thread safe would go here.
            
                //Simulate some work
                Thread.Sleep(500);

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
            
                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }

    }
}  
Imports System
Imports System.Threading

Namespace InterlockedExchange_Example
    Class MyInterlockedExchangeExampleClass
        '0 for false, 1 for true.
        Private Shared usingResource As Integer = 0

        Private Const numThreadIterations As Integer = 5
        Private Const numThreads As Integer = 10

        <MTAThread> _
        Shared Sub Main()
            Dim myThread As Thread
            Dim rnd As New Random()

            Dim i As Integer
            For i = 0 To numThreads - 1
                myThread = New Thread(AddressOf MyThreadProc)
                myThread.Name = String.Format("Thread{0}", i + 1)

                'Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000))
                myThread.Start()
            Next i
        End Sub 'Main

        Private Shared Sub MyThreadProc()
            Dim i As Integer
            For i = 0 To numThreadIterations - 1
                UseResource()

                'Wait 1 second before next attempt.
                Thread.Sleep(1000)
            Next i
        End Sub 

        'A simple method that denies reentrancy.
        Shared Function UseResource() As Boolean
            '0 indicates that the method is not in use.
            If 0 = Interlocked.Exchange(usingResource, 1) Then
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name)

                'Code to access a resource that is not thread safe would go here.
                'Simulate some work
                Thread.Sleep(500)

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name)

                'Release the lock
                Interlocked.Exchange(usingResource, 0)
                Return True
            Else
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name)
                Return False
            End If
        End Function 
    End Class 
End Namespace 

備註

這個類別的方法來協助防止當排程器會切換內容,直到有執行緒在更新的變數,可由其他執行緒,或在不同的處理器上同時執行兩個執行緒可能會發生的錯誤。The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors. 這個類別的成員不會擲回例外狀況。The members of this class do not throw exceptions.

IncrementDecrement方法遞增或遞減變數,並將產生的值儲存在單一作業。The Increment and Decrement methods increment or decrement a variable and store the resulting value in a single operation. 在大部分的電腦上遞增變數不是不可部分完成的作業,需要下列步驟:On most computers, incrementing a variable is not an atomic operation, requiring the following steps:

  1. 將值從執行個體變數載入暫存器。Load a value from an instance variable into a register.

  2. 遞增或遞減的值。Increment or decrement the value.

  3. 將值儲存在執行個體變數。Store the value in the instance variable.

如果您不要使用IncrementDecrement,執行緒可以在執行前兩個步驟之後被優先佔用。If you do not use Increment and Decrement, a thread can be preempted after executing the first two steps. 接著,另一個執行緒可執行所有的三個步驟。Another thread can then execute all three steps. 當第一個執行緒繼續執行時,它會覆寫執行個體變數中的值,而且遞增或遞減的第二個執行緒所執行的效果會遺失。When the first thread resumes execution, it overwrites the value in the instance variable, and the effect of the increment or decrement performed by the second thread is lost.

Add方法以不可分割方式將整數值新增至整數變數,並傳回新的變數值。The Add method atomically adds an integer value to an integer variable and returns the new value of the variable.

Exchange方法會以不可分割方式交換指定變數的值。The Exchange method atomically exchanges the values of the specified variables. CompareExchange方法結合了兩項作業: 比較兩個值,並儲存第三個值其中一個變數,並根據比較結果。The CompareExchange method combines two operations: comparing two values and storing a third value in one of the variables, based on the outcome of the comparison. 比較和交換作業成為不可部分完成的作業。The compare and exchange operations are performed as an atomic operation.

請確定任何寫入或讀取權限共用的變數是不可部分完成。Ensure that any write or read access to a shared variable is atomic. 否則,資料可能會損毀,或載入的值可能不正確。Otherwise, the data might be corrupted or the loaded value might be incorrect.

方法

Add(Int32, Int32) Add(Int32, Int32) Add(Int32, Int32) Add(Int32, Int32)

將兩個 32 位元整數加相,並以總和取代第一個整數,成為不可部分完成的作業。Adds two 32-bit integers and replaces the first integer with the sum, as an atomic operation.

Add(Int64, Int64) Add(Int64, Int64) Add(Int64, Int64) Add(Int64, Int64)

將兩個 64 位元整數加相,並以總和取代第一個整數,成為不可部分完成的作業。Adds two 64-bit integers and replaces the first integer with the sum, as an atomic operation.

CompareExchange(Double, Double, Double) CompareExchange(Double, Double, Double) CompareExchange(Double, Double, Double) CompareExchange(Double, Double, Double)

比較兩個雙精確度浮點數是否相等;如果相等,則取代第一個值。Compares two double-precision floating point numbers for equality and, if they are equal, replaces the first value.

CompareExchange(Int32, Int32, Int32) CompareExchange(Int32, Int32, Int32) CompareExchange(Int32, Int32, Int32) CompareExchange(Int32, Int32, Int32)

比較兩個 32 位元帶正負號的整數是否相等,如果相等,則取代第一個值。Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.

CompareExchange(Int64, Int64, Int64) CompareExchange(Int64, Int64, Int64) CompareExchange(Int64, Int64, Int64) CompareExchange(Int64, Int64, Int64)

比較兩個 64 位元帶正負號的整數是否相等,如果相等,則取代第一個值。Compares two 64-bit signed integers for equality and, if they are equal, replaces the first value.

CompareExchange(IntPtr, IntPtr, IntPtr) CompareExchange(IntPtr, IntPtr, IntPtr) CompareExchange(IntPtr, IntPtr, IntPtr) CompareExchange(IntPtr, IntPtr, IntPtr)

比較兩個平台特定的控制代碼或指標是否相等;如果相等,則取代第一個。Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one.

CompareExchange(Object, Object, Object) CompareExchange(Object, Object, Object) CompareExchange(Object, Object, Object) CompareExchange(Object, Object, Object)

比較兩個物件的參考是否相等;如果相等,則取代第一個物件。Compares two objects for reference equality and, if they are equal, replaces the first object.

CompareExchange(Single, Single, Single) CompareExchange(Single, Single, Single) CompareExchange(Single, Single, Single) CompareExchange(Single, Single, Single)

比較兩個單精確度浮點數是否相等;如果相等,則取代第一個值。Compares two single-precision floating point numbers for equality and, if they are equal, replaces the first value.

CompareExchange<T>(T, T, T) CompareExchange<T>(T, T, T) CompareExchange<T>(T, T, T) CompareExchange<T>(T, T, T)

比較指定參考型別 T 的兩個執行個體是否參考相等;如果相等,則取代第一個。Compares two instances of the specified reference type T for reference equality and, if they are equal, replaces the first one.

Decrement(Int32) Decrement(Int32) Decrement(Int32) Decrement(Int32)

遞減特定變數並將結果儲存起來,成為不可部分完成的作業。Decrements a specified variable and stores the result, as an atomic operation.

Decrement(Int64) Decrement(Int64) Decrement(Int64) Decrement(Int64)

遞減特定變數並將結果儲存起來,成為不可部分完成的作業。Decrements the specified variable and stores the result, as an atomic operation.

Exchange(Single, Single) Exchange(Single, Single) Exchange(Single, Single) Exchange(Single, Single)

將單精確度浮點數設定為指定值,然後傳回原始值,成為不可部分完成的作業。Sets a single-precision floating point number to a specified value and returns the original value, as an atomic operation.

Exchange(Object, Object) Exchange(Object, Object) Exchange(Object, Object) Exchange(Object, Object)

將物件設定為指定值,然後傳回原始物件的參考,成為不可部分完成的作業。Sets an object to a specified value and returns a reference to the original object, as an atomic operation.

Exchange(IntPtr, IntPtr) Exchange(IntPtr, IntPtr) Exchange(IntPtr, IntPtr) Exchange(IntPtr, IntPtr)

將平台特定的控制代碼或指標設定為指定值,然後傳回原始值,成為不可部分完成的作業。Sets a platform-specific handle or pointer to a specified value and returns the original value, as an atomic operation.

Exchange(Double, Double) Exchange(Double, Double) Exchange(Double, Double) Exchange(Double, Double)

將雙精確度浮點數設定為指定值,然後傳回原始值,成為不可部分完成的作業。Sets a double-precision floating point number to a specified value and returns the original value, as an atomic operation.

Exchange(Int32, Int32) Exchange(Int32, Int32) Exchange(Int32, Int32) Exchange(Int32, Int32)

將 32 位元帶正負號的整數設定為指定值,然後傳回原始值,成為不可部分完成的作業。Sets a 32-bit signed integer to a specified value and returns the original value, as an atomic operation.

Exchange(Int64, Int64) Exchange(Int64, Int64) Exchange(Int64, Int64) Exchange(Int64, Int64)

將 64 位元帶正負號的整數設定為指定值,然後傳回原始值,成為不可部分完成的作業。Sets a 64-bit signed integer to a specified value and returns the original value, as an atomic operation.

Exchange<T>(T, T) Exchange<T>(T, T) Exchange<T>(T, T) Exchange<T>(T, T)

將指定類型 T 的變數設定為指定值,然後傳回原始值,成為不可部分完成的作業。Sets a variable of the specified type T to a specified value and returns the original value, as an atomic operation.

Increment(Int32) Increment(Int32) Increment(Int32) Increment(Int32)

遞增特定變數並將結果儲存起來,成為不可部分完成的作業。Increments a specified variable and stores the result, as an atomic operation.

Increment(Int64) Increment(Int64) Increment(Int64) Increment(Int64)

遞增特定變數並將結果儲存起來,成為不可部分完成的作業。Increments a specified variable and stores the result, as an atomic operation.

MemoryBarrier() MemoryBarrier() MemoryBarrier() MemoryBarrier()

同步記憶體存取,如下所示:執行目前執行緒的處理器無法用這種方式重新排列指令:呼叫 MemoryBarrier() 前的記憶體存取在呼叫 MemoryBarrier() 後的記憶體存取之後執行。Synchronizes memory access as follows: The processor that executes the current thread cannot reorder instructions in such a way that memory accesses before the call to MemoryBarrier() execute after memory accesses that follow the call to MemoryBarrier().

MemoryBarrierProcessWide() MemoryBarrierProcessWide() MemoryBarrierProcessWide() MemoryBarrierProcessWide()

提供整個處理序範圍的記憶體屏障,以確保來自任何 CPU 的讀取和寫入都無法穿越屏障。Provides a process-wide memory barrier that ensures that reads and writes from any CPU cannot move across the barrier.

Read(Int64) Read(Int64) Read(Int64) Read(Int64)

傳回 64 位元的值 (載入為不可部分完成的作業)。Returns a 64-bit value, loaded as an atomic operation.

SpeculationBarrier() SpeculationBarrier() SpeculationBarrier() SpeculationBarrier()

定義記憶體柵欄以封鎖這個點之後的理論式執行,直到擱置的讀取和寫入完成為止。Defines a memory fence that blocks speculative execution past this point until pending reads and writes are complete.

適用於

執行緒安全性

此型別具備執行緒安全。This type is thread safe.

另請參閱