Interlocked Interlocked Interlocked Interlocked Class

Definición

Proporciona operaciones atómicas para las variables compartidas por varios subprocesos.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
Herencia
InterlockedInterlockedInterlockedInterlocked

Ejemplos

El ejemplo de código siguiente muestra un mecanismo de bloqueo de recursos seguro para subprocesos.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 

Comentarios

Los métodos de esta clase ayudan a protegerse frente a errores que pueden producirse cuando el programador cambia de contexto mientras un subproceso está actualizando una variable que se puede acceder por otros subprocesos, o cuando dos subprocesos se ejecutan simultáneamente en procesadores separados.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. Los miembros de esta clase no producen excepciones.The members of this class do not throw exceptions.

El Increment y Decrement métodos aumentar o reducir una variable y almacenar el valor resultante en una sola operación.The Increment and Decrement methods increment or decrement a variable and store the resulting value in a single operation. En la mayoría de los equipos, el incremento de una variable no es una operación atómica, que requieren los pasos siguientes:On most computers, incrementing a variable is not an atomic operation, requiring the following steps:

  1. Cargar un valor de una variable de instancia en un registro.Load a value from an instance variable into a register.

  2. Incrementar o disminuir el valor.Increment or decrement the value.

  3. Store el valor en la variable de instancia.Store the value in the instance variable.

Si no usas Increment y Decrement, un subproceso puede ser adelantado después de ejecutar los dos primeros pasos.If you do not use Increment and Decrement, a thread can be preempted after executing the first two steps. Otro subproceso, a continuación, puede ejecutar estos tres pasos.Another thread can then execute all three steps. Cuando el primer subproceso reanuda la ejecución, sobrescribe el valor de la variable de instancia y se pierde el efecto del incremento o decremento realizadas por el segundo subproceso.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.

El Add atómicamente, el método agrega un valor entero a una variable de entero y devuelve el nuevo valor de la variable.The Add method atomically adds an integer value to an integer variable and returns the new value of the variable.

El Exchange método intercambia los valores de las variables especificadas atómicamente.The Exchange method atomically exchanges the values of the specified variables. El CompareExchange método combina dos operaciones: compara dos valores y almacena un tercer valor en una de las variables, en función del resultado de la comparación.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. Las operaciones de comparación e intercambio se realizan como una operación atómica.The compare and exchange operations are performed as an atomic operation.

Asegúrese de que cualquier escritura o acceso de lectura a una variable compartida es atómica.Ensure that any write or read access to a shared variable is atomic. En caso contrario, los datos podrían estar dañados o valor cargado podría ser incorrecto.Otherwise, the data might be corrupted or the loaded value might be incorrect.

Métodos

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

Agrega dos enteros de 32 bits y reemplaza el primer entero por la suma, como una operación atómica.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)

Agrega dos enteros de 64 bits y reemplaza el primer entero por la suma, como una operación atómica.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)

Compara dos números de punto flotante de precisión doble para comprobar si son iguales y, si lo son, reemplaza el primero de los valores.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)

Compara dos enteros de 32 bits con signo para comprobar si son iguales y, si lo son, reemplaza el primer valor.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)

Compara dos enteros de 64 bits con signo para comprobar si son iguales y, si lo son, reemplaza el primer valor.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)

Compara dos identificadores o punteros específicos de plataforma para comprobar si son iguales y, si lo son, reemplaza el primero.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)

Compara dos objetos para comprobar si sus referencias son iguales y, si lo son, reemplaza el primero de los objetos.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)

Compara dos números de punto flotante de precisión sencilla para comprobar si son iguales y, si lo son, reemplaza el primero de los valores.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)

Compara dos instancias del tipo de referencia especificado T para comprobar si las referencias son iguales y, si lo son, reemplaza la primera.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)

Disminuye el valor de una variable especificada y almacena el resultado, como una operación atómica.Decrements a specified variable and stores the result, as an atomic operation.

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

Disminuye el valor de la variable especificada y almacena el resultado, como una operación atómica.Decrements the specified variable and stores the result, as an atomic operation.

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

Establece un número de punto flotante de precisión sencilla en un valor especificado y devuelve el valor original, como una operación atómica.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)

Establece un objeto en un valor especificado y devuelve una referencia al objeto original, como una operación atómica.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)

Establece un puntero o identificador específico de plataforma en un valor especificado y devuelve el valor original, como una operación atómica.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)

Establece un número de punto flotante de precisión doble en un valor especificado y devuelve el valor original, como una operación atómica.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)

Establece un entero de 32 bits con signo en un valor especificado y devuelve el valor original, como una operación atómica.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)

Establece un entero de 64 bits con signo en un valor especificado y devuelve el valor original, como una operación atómica.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)

Establece una variable del tipo T especificado en un valor determinado y devuelve el valor original, como una operación atómica.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)

Aumenta el valor de una variable especificada y almacena el resultado, como una operación atómica.Increments a specified variable and stores the result, as an atomic operation.

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

Aumenta el valor de una variable especificada y almacena el resultado, como una operación atómica.Increments a specified variable and stores the result, as an atomic operation.

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

Sincroniza el acceso a la memoria de la siguiente forma: El procesador que ejecuta el subproceso actual no puede reordenar las instrucciones de forma que los accesos a la memoria anteriores a la llamada a MemoryBarrier() se ejecuten después de los accesos a memoria posteriores a la llamada a 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()

Proporciona una barrera de memoria para todo el proceso con el fin de asegurar que las operaciones de lectura y escritura desde cualquier CPU no puedan superar la barrera.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)

Devuelve un valor de 64 bits, cargado como una operación atómica.Returns a 64-bit value, loaded as an atomic operation.

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

Se aplica a

Seguridad para subprocesos

Este tipo es seguro para la ejecución de subprocesos.This type is thread safe.

Consulte también: