Interlocked Třída

Definice

Poskytuje atomické operace pro proměnné, které jsou sdíleny více vlákny.

public ref class Interlocked abstract sealed
public ref class Interlocked sealed
public static class Interlocked
public sealed class Interlocked
type Interlocked = class
Public Class Interlocked
Public NotInheritable Class Interlocked
Dědičnost
Interlocked

Příklady

Následující příklad kódu ukazuje mechanismus uzamčení prostředků bezpečných vlákny.

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.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

        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

Poznámky

Metody této třídy pomáhají chránit před chybami, ke kterým může dojít, když plánovač přepne kontexty v době, kdy vlákno aktualizuje proměnnou, ke které lze přistupovat jinými vlákny, nebo když se dvě vlákna spouští souběžně na samostatných procesorech. Členové této třídy nevyvolají výjimky.

Metody Increment inkrementuje Decrement nebo dekrementuje proměnnou a uloží výslednou hodnotu do jedné operace. Ve většině počítačů není přírůstkem proměnné atomická operace, která vyžaduje následující kroky:

  1. Načtěte hodnotu z proměnné instance do registru.

  2. Zvýšení nebo snížení hodnoty

  3. Uložte hodnotu do proměnné instance.

Pokud ho nepoužíváte Increment a Decrementpo provedení prvních dvou kroků může být vlákno předem připravené. Další vlákno pak může provést všechny tři kroky. Když první vlákno obnoví provádění, přepíše hodnotu v proměnné instance a účinek přírůstku nebo dekrementu provedeného druhým vláknem se ztratí.

Metoda Add atomicky přidá celočíselnou hodnotu do celočíselné proměnné a vrátí novou hodnotu proměnné.

Metoda Exchange atomicky vyměňuje hodnoty zadaných proměnných. Metoda CompareExchange kombinuje dvě operace: porovnávání dvou hodnot a uložení třetí hodnoty v jedné z proměnných na základě výsledku porovnání. Operace porovnání a výměny se provádějí jako atomická operace.

Ujistěte se, že jakýkoli přístup pro zápis nebo čtení ke sdílené proměnné je atomický. V opačném případě mohou být data poškozena nebo načtená hodnota může být nesprávná.

Metody

Add(Int32, Int32)

Přidá dvě 32bitová celá čísla a nahradí první celé číslo součtem jako atomické operace.

Add(Int64, Int64)

Přidá dvě 64bitová celá čísla a nahradí první celé číslo součtem jako atomické operace.

Add(UInt32, UInt32)

Přidá dvě 32bitová celá čísla bez znaménka a nahradí první celé číslo součtem jako atomické operace.

Add(UInt64, UInt64)

Přidá dvě 64bitová celá čísla bez znaménka a nahradí první celé číslo součtem jako atomické operace.

And(Int32, Int32)

Bitové "ands" dvě 32bitová celá čísla a nahradí první celé číslo výsledkem atomické operace.

And(Int64, Int64)

Bitové "ands" dvě 64bitová celá čísla a nahradí první celé číslo výsledkem atomické operace.

And(UInt32, UInt32)

Bitwise "ands" dvě 32bitové celé číslo bez znaménka a nahradí první celé číslo výsledkem, jako atomická operace.

And(UInt64, UInt64)

Bitové "ands" dvě 64bitová celá čísla bez znaménka a nahradí první celé číslo výsledkem jako atomická operace.

CompareExchange(Double, Double, Double)

Porovná dvě čísla s plovoucí desetinnou čárkou s dvojitou přesností pro rovnost a pokud jsou stejná, nahradí první hodnotu.

CompareExchange(Int32, Int32, Int32)

Porovná dvě 32bitová celá čísla s výjimkou rovnosti a pokud jsou stejné, nahradí první hodnotu.

CompareExchange(Int64, Int64, Int64)

Porovná dvě 64bitová 64bitová celá čísla pro rovnost a pokud jsou stejné, nahradí první hodnotu.

CompareExchange(IntPtr, IntPtr, IntPtr)

Porovná dva úchyty nebo ukazatele specifické pro platformu pro rovnost a pokud jsou stejné, nahradí první.

CompareExchange(Object, Object, Object)

Porovná dva objekty pro rovnost odkazů a pokud jsou stejné, nahradí první objekt.

CompareExchange(Single, Single, Single)

Porovná dvě čísla s plovoucí desetinou čárkou pro rovnost a pokud jsou stejná, nahradí první hodnotu.

CompareExchange(UInt32, UInt32, UInt32)

Porovná dvě 32bitová celá čísla bez znaménka pro rovnost a pokud jsou stejné, nahradí první hodnotu.

CompareExchange(UInt64, UInt64, UInt64)

Porovná dvě 64bitová celá čísla bez znaménka pro rovnost a pokud jsou stejné, nahradí první hodnotu.

CompareExchange(UIntPtr, UIntPtr, UIntPtr)

Porovná dva úchyty nebo ukazatele specifické pro platformu pro rovnost a pokud jsou stejné, nahradí první.

CompareExchange<T>(T, T, T)

Porovná dvě instance zadaného referenčního typu T pro rovnost odkazů a pokud jsou stejné, nahradí první.

Decrement(Int32)

Sníží zadanou proměnnou a uloží výsledek jako atomická operace.

Decrement(Int64)

Sníží zadanou proměnnou a uloží výsledek jako atomická operace.

Decrement(UInt32)

Sníží zadanou proměnnou a uloží výsledek jako atomická operace.

Decrement(UInt64)

Sníží zadanou proměnnou a uloží výsledek jako atomická operace.

Exchange(Double, Double)

Nastaví číslo s plovoucí desetinnou čárkou s dvojitou přesností na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(Int32, Int32)

Nastaví 32bitové celé číslo podepsané na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(Int64, Int64)

Nastaví 64bitové celé číslo podepsané na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(IntPtr, IntPtr)

Nastaví popisovač specifický pro platformu nebo ukazatel na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(Object, Object)

Nastaví objekt na zadanou hodnotu a vrátí odkaz na původní objekt jako atomické operace.

Exchange(Single, Single)

Nastaví číslo s plovoucí desetinnou čárkou s jednou přesností na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(UInt32, UInt32)

Nastaví 32bitové celé číslo bez znaménka na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(UInt64, UInt64)

Nastaví 64bitové celé číslo bez znaménka na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange(UIntPtr, UIntPtr)

Nastaví popisovač specifický pro platformu nebo ukazatel na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Exchange<T>(T, T)

Nastaví proměnnou zadaného typu T na zadanou hodnotu a vrátí původní hodnotu jako atomické operace.

Increment(Int32)

Zvýší zadanou proměnnou a uloží výsledek jako atomická operace.

Increment(Int64)

Zvýší zadanou proměnnou a uloží výsledek jako atomická operace.

Increment(UInt32)

Zvýší zadanou proměnnou a uloží výsledek jako atomická operace.

Increment(UInt64)

Zvýší zadanou proměnnou a uloží výsledek jako atomická operace.

MemoryBarrier()

Synchronizuje přístup k paměti následujícím způsobem: Procesor, který spouští aktuální vlákno, nemůže změnit pořadí pokynů tak, aby paměť přistupovala před voláním, aby se MemoryBarrier() spustila po přístupu k paměti, které následují za voláním MemoryBarrier().

MemoryBarrierProcessWide()

Poskytuje bariéru paměti pro celý proces, která zajišťuje, že čtení a zápisy z jakéhokoli procesoru nemůže přecházet přes bariéru.

Or(Int32, Int32)

Bitové "ors" dvě 32bitová celá čísla a nahradí první celé číslo výsledkem atomické operace.

Or(Int64, Int64)

Bitové "ors" dvě 64bitová celá čísla a nahradí první celé číslo výsledkem atomické operace.

Or(UInt32, UInt32)

Bitové "ors" dvě 32bitová celá čísla bez znaménka a nahradí první celé číslo výsledkem jako atomická operace.

Or(UInt64, UInt64)

Bitové "ors" dvě 64bitová celá čísla bez znaménka a nahradí první celé číslo výsledkem jako atomická operace.

Read(Int64)

Vrátí 64bitovou hodnotu načtenou jako atomická operace.

Read(UInt64)

Vrátí 64bitovou hodnotu bez znaménka načtenou jako atomická operace.

SpeculationBarrier()

Definuje plot paměti, který blokuje spekulativní spuštění po tomto bodu, dokud nebudou dokončeny čekající čtení a zápisy.

Platí pro

Bezpečný přístup z více vláken

Tento typ je bezpečný pro přístup z více vláken.

Viz také