Información general sobre las primitivas de sincronizaciónOverview of synchronization primitives

.NET proporciona una variedad de tipos que puede usar para sincronizar el acceso a un recurso compartido o coordinar la interacción de subprocesos..NET provides a range of types that you can use to synchronize access to a shared resource or coordinate thread interaction.

Importante

Use la misma instancia primitiva de sincronización para proteger todos los accesos a un recurso compartido.Use the same synchronization primitive instance to protect every access to a shared resource. Varios subprocesos pueden acceder a un recurso al mismo tiempo si usa diferentes instancias primitivas de sincronización para proteger el acceso a un recurso o algunas partes del código acceden directamente a un recurso.Multiple threads can access a resource concurrently if you use different synchronization primitive instances to protect access to a resource or some parts of code access a resource directly.

Clase WaitHandle y tipos de sincronización ligerosWaitHandle class and lightweight synchronization types

Varias primitivas de sincronización de .NET derivan de la clase System.Threading.WaitHandle, que encapsula un controlador de sincronización del sistema operativo nativo y usa un mecanismo de señalización para la interacción de subprocesos.Multiple .NET synchronization primitives derive from the System.Threading.WaitHandle class, which encapsulates a native operating system synchronization handle and uses a signaling mechanism for thread interaction. Esas clases incluyen:Those classes include:

  • System.Threading.Mutex, que concede acceso exclusivo a un recurso compartido.System.Threading.Mutex, which grants exclusive access to a shared resource. El estado de una exclusión mutua se señala si no es propiedad de ningún subproceso.The state of a mutex is signaled if no thread owns it.
  • System.Threading.Semaphore, que limita el número de subprocesos que pueden tener acceso a un recurso compartido o grupo de recursos simultáneamente.System.Threading.Semaphore, which limits the number of threads that can access a shared resource or a pool of resources concurrently. El estado de un semáforo se establece como señalizado cuando su recuento es mayor que cero y como no señalizado cuando su recuento es cero.The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero.
  • System.Threading.EventWaitHandle, que representa un evento de sincronización de subprocesos y puede estar en un estado señalizado o no señalizado.System.Threading.EventWaitHandle, which represents a thread synchronization event and can be either in a signaled or unsignaled state.
  • System.Threading.AutoResetEvent, que se deriva de EventWaitHandle y, cuando está señalizada, se restablece automáticamente a un estado no señalizado después de liberar un subproceso en espera único.System.Threading.AutoResetEvent, which derives from EventWaitHandle and, when signaled, resets automatically to an unsignaled state after releasing a single waiting thread.
  • System.Threading.ManualResetEvent, que se deriva de EventWaitHandle y, cuando está señalizado, permanece en un estado señalizado hasta que se llama al método Reset.System.Threading.ManualResetEvent, which derives from EventWaitHandle and, when signaled, stays in a signaled state until the Reset method is called.

En .NET Framework, dado que WaitHandle deriva de System.MarshalByRefObject, estos tipos se pueden usar para sincronizar las actividades de subprocesos en los límites del dominio de aplicación.In the .NET Framework, because WaitHandle derives from System.MarshalByRefObject, these types can be used to synchronize the activities of threads across application domain boundaries.

En .NET Framework y .NET Core, algunos de estos tipos pueden representar los controladores de sincronización del sistema con nombre, que son visibles en todo el sistema operativo y se pueden usar para la sincronización entre procesos:In the .NET Framework and .NET Core, some of these types can represent named system synchronization handles, which are visible throughout the operating system and can be used for the inter-process synchronization:

  • Mutex (.NET Framework y .NET Core),Mutex (.NET Framework and .NET Core),
  • Semaphore (.NET Framework y .NET Core en Windows),Semaphore (.NET Framework and .NET Core on Windows),
  • EventWaitHandle (.NET Framework y .NET Core en Windows).EventWaitHandle (.NET Framework and .NET Core on Windows).

Para más información, vea la referencia de API WaitHandle.For more information, see the WaitHandle API reference.

Los tipos de sincronización ligeros no se basan en los controladores del sistema operativo subyacentes y suelen proporcionar un mejor rendimiento.Lightweight synchronization types don't rely on underlying operating system handles and typically provide better performance. Sin embargo, no se pueden usar para la sincronización entre procesos.However, they cannot be used for the inter-process synchronization. Utilice esos tipos para la sincronización de subprocesos dentro de una aplicación.Use those types for thread synchronization within one application.

Algunos de esos tipos son alternativas a los tipos derivados de WaitHandle.Some of those types are alternatives to the types derived from WaitHandle. Por ejemplo, SemaphoreSlim es una alternativa ligera a Semaphore.For example, SemaphoreSlim is a lightweight alternative to Semaphore.

Sincronización del acceso a un recurso compartidoSynchronization of access to a shared resource

.NET proporciona un intervalo de primitivas de sincronización para controlar el acceso a un recurso compartido por varios subprocesos..NET provides a range of synchronization primitives to control access to a shared resource by multiple threads.

Monitor (clase)Monitor class

La clase System.Threading.Monitor concede acceso mutuamente exclusivo a un recurso compartido mediante la adquisición o liberación de un bloqueo en el objeto que identifica el recurso.The System.Threading.Monitor class grants mutually exclusive access to a shared resource by acquiring or releasing a lock on the object that identifies the resource. Mientras se mantiene un bloqueo, el subproceso que lo mantiene puede volver a adquirir y liberar dicho bloqueo.While a lock is held, the thread that holds the lock can again acquire and release the lock. Ningún otro subproceso puede adquirir el bloqueo y el método Monitor.Enter espera hasta que el bloqueo se libera.Any other thread is blocked from acquiring the lock and the Monitor.Enter method waits until the lock is released. El método Enter adquiere un bloqueo liberado.The Enter method acquires a released lock. También puede usar el método Monitor.TryEnter para especificar la cantidad de tiempo durante el cual un subproceso intenta adquirir un bloqueo.You can also use the Monitor.TryEnter method to specify the amount of time during which a thread attempts to acquire a lock. Dado que la clase Monitor tiene afinidad de subproceso, el subproceso que adquirió un bloqueo debe liberarlo mediante una llamada al método Monitor.Exit.Because the Monitor class has thread affinity, the thread that acquired a lock must release the lock by calling the Monitor.Exit method.

Puede coordinar la interacción de subprocesos que adquieren un bloqueo en el mismo objeto mediante los métodos Monitor.Wait, Monitor.Pulse y Monitor.PulseAll.You can coordinate the interaction of threads that acquire a lock on the same object by using the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll methods.

Para más información, vea la referencia de API Monitor.For more information, see the Monitor API reference.

Nota

Use la instrucción lock en C# y la instrucción SyncLock en Visual Basic para sincronizar el acceso a un recurso compartido en lugar de usar la clase Monitor directamente.Use the lock statement in C# and the SyncLock statement in Visual Basic to synchronize access to a shared resource instead of using the Monitor class directly. Esas instrucciones se implementan mediante los métodos Enter y Exit, y usa un bloqueo try…finally para asegurarse de que se libere el bloqueo.Those statements are implemented by using the Enter and Exit methods and a try…finally block to ensure that the acquired lock is always released.

Mutex (clase)Mutex class

La clase System.Threading.Mutex, como Monitor, concede acceso exclusivo a un recurso compartido.The System.Threading.Mutex class, like Monitor, grants exclusive access to a shared resource. Utilice una de las sobrecargas del método Mutex.WaitOne para solicitar la propiedad de una exclusión mutua.Use one of the Mutex.WaitOne method overloads to request the ownership of a mutex. Al igual que Monitor, Mutex tiene afinidad de subproceso y el subproceso que adquirió una exclusión mutua debe liberarlo llamando al método Mutex.ReleaseMutex.Like Monitor, Mutex has thread affinity and the thread that acquired a mutex must release it by calling the Mutex.ReleaseMutex method.

A diferencia de Monitor, la clase Mutex puede usarse para la sincronización entre procesos.Unlike Monitor, the Mutex class can be used for inter-process synchronization. Para ello, use una exclusión mutua con nombre, que es visible en todo el sistema operativo.To do that, use a named mutex, which is visible throughout the operating system. Para crear una instancia de la exclusión mutua con nombre, use un constructor de exclusión mutua que especifica un nombre.To create a named mutex instance, use a Mutex constructor that specifies a name. También se puede llamar al método Mutex.OpenExisting para abrir una exclusión mutua del sistema existente.You also can call the Mutex.OpenExisting method to open an existing named system mutex.

Para más información, vea el artículo Mutexes y la referencia de API Mutex.For more information, see the Mutexes article and the Mutex API reference.

SpinLock (estructura)SpinLock structure

La estructura System.Threading.SpinLock, como Monitor, concede acceso exclusivo a un recurso compartido en función de la disponibilidad de un bloqueo.The System.Threading.SpinLock structure, like Monitor, grants exclusive access to a shared resource based on the availability of a lock. Cuando SpinLock intenta adquirir un bloqueo que no está disponible, espera en un bucle, y realiza comprobaciones repetidamente hasta que dicho bloqueo esté disponible.When SpinLock attempts to acquire a lock that is unavailable, it waits in a loop, repeatedly checking until the lock becomes available.

Para más información sobre las ventajas e inconvenientes del uso de un bloqueo de giro, vea el artículo SpinLock y la referencia de API SpinLock.For more information about the benefits and drawbacks of using spin lock, see the SpinLock article and the SpinLock API reference.

ReaderWriterLockSlim (clase)ReaderWriterLockSlim class

La clase System.Threading.ReaderWriterLockSlim concede acceso exclusivo a un recurso compartido para escritura y permite que varios subprocesos accedan al recurso simultáneamente para lectura.The System.Threading.ReaderWriterLockSlim class grants exclusive access to a shared resource for writing and allows multiple threads to access the resource simultaneously for reading. Es posible que desee utilizar ReaderWriterLockSlim para sincronizar el acceso a una estructura de datos compartida que admita operaciones de lectura seguras para subprocesos, pero que requiera acceso exclusivo para realizar la operación de escritura.You might want to use ReaderWriterLockSlim to synchronize access to a shared data structure that supports thread-safe read operations, but requires exclusive access to perform write operation. Cuando un subproceso solicita acceso exclusivo (por ejemplo, llamando al método ReaderWriterLockSlim.EnterWriteLock), las solicitudes posteriores del lector y el escritor se bloquean hasta que todos los lectores existentes han salido del bloqueo y el escritor ha entrado y salido de dicho bloqueo.When a thread requests exclusive access (for example, by calling the ReaderWriterLockSlim.EnterWriteLock method), subsequent reader and writer requests block until all existing readers have exited the lock, and the writer has entered and exited the lock.

Para más información, vea la referencia de API ReaderWriterLockSlim.For more information, see the ReaderWriterLockSlim API reference.

Semaphore y SemaphoreSlim (clases)Semaphore and SemaphoreSlim classes

Las clases System.Threading.Semaphore y System.Threading.SemaphoreSlim limitan el número de subprocesos que pueden tener acceso a un recurso compartido o grupo de recursos simultáneamente.The System.Threading.Semaphore and System.Threading.SemaphoreSlim classes limit the number of threads that can access a shared resource or a pool of resources concurrently. Los demás subprocesos que soliciten el recurso esperarán hasta que un subproceso libere el semáforo.Additional threads that request the resource wait until any thread releases the semaphore. Dado que el semáforo no tiene afinidad de subproceso, un subproceso puede adquirir el semáforo y otro puede liberarlo.Because the semaphore doesn't have thread affinity, a thread can acquire the semaphore and another one can release it.

SemaphoreSlim es una alternativa ligera a Semaphore y solo se puede usar para la sincronización dentro de un límite de un único proceso.SemaphoreSlim is a lightweight alternative to Semaphore and can be used only for synchronization within a single process boundary.

En Windows, puede usar Semaphore para la sincronización entre procesos.On Windows, you can use Semaphore for the inter-process synchronization. Para hacerlo, cree una instancia de Semaphore que represente un semáforo de sistema con nombre mediante el uso de uno de los constructores Semaphore que especifica un nombre o el método Semaphore.OpenExisting.To do that, create a Semaphore instance that represents a named system semaphore by using one of the Semaphore constructors that specifies a name or the Semaphore.OpenExisting method. SemaphoreSlim no es compatible con los semáforos con nombre del sistema.SemaphoreSlim doesn't support named system semaphores.

Para más información, consulte el artículo Semaphore y SemaphoreSlim y la referencia de API Semaphore o SemaphoreSlim.For more information, see the Semaphore and SemaphoreSlim article and the Semaphore or SemaphoreSlim API reference.

Interacción de subprocesos o señalizaciónThread interaction, or signaling

Interacción de subprocesos (o señalización de subprocesos) significa que un subproceso debe esperar la notificación o una señal de uno o varios subprocesos para poder continuar.Thread interaction (or thread signaling) means that a thread must wait for notification, or a signal, from one or more threads in order to proceed. Por ejemplo, si un subproceso A llama al método Thread.Join del subproceso B, un subproceso A se bloquea hasta que el subproceso B finaliza.For example, if thread A calls the Thread.Join method of thread B, thread A is blocked until thread B completes. Las primitivas de sincronización descritas en la sección anterior proporcionan un mecanismo diferente para la señalización: al liberar un bloqueo, un subproceso notifica a otro subproceso que puede continuar adquiriendo el bloqueo.The synchronization primitives described in the preceding section provide a different mechanism for signaling: by releasing a lock, a thread notifies another thread that it can proceed by acquiring the lock.

En esta sección se describen construcciones adicionales de señalización proporcionados por. NET.This section describes additional signaling constructs provided by .NET.

EventWaitHandle, AutoResetEvent, ManualResetEvent y ManualResetEventSlim (clases)EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim classes

La clase System.Threading.EventWaitHandle representa un evento de sincronización de subprocesos.The System.Threading.EventWaitHandle class represents a thread synchronization event.

Un evento de sincronización puede estar en un estado de no señalizado o señalizado.A synchronization event can be either in an unsignaled or signaled state. Cuando el estado de un evento es señalizado, un subproceso que llama a la sobrecarga WaitOne del evento se bloquea hasta que un evento se señaliza.When the state of an event is unsignaled, a thread that calls the event's WaitOne overload is blocked until an event is signaled. El método EventWaitHandle.Set establece el estado de un evento en señalizado.The EventWaitHandle.Set method sets the state of an event to signaled.

El comportamiento de una clase EventWaitHandle que se haya señalizado depende de su modo de restablecimiento:The behavior of an EventWaitHandle that has been signaled depends on its reset mode:

En Windows, puede usar EventWaitHandle para la sincronización entre procesos.On Windows, you can use EventWaitHandle for the inter-process synchronization. Para hacerlo, cree una instancia de EventWaitHandle que represente un semáforo de sincronización del sistema con nombre mediante el uso de uno de los constructores EventWaitHandle que especifica un nombre o el método EventWaitHandle.OpenExisting.To do that, create a EventWaitHandle instance that represents a named system synchronization event by using one of the EventWaitHandle constructors that specifies a name or the EventWaitHandle.OpenExisting method.

Para obtener más información, consulte el artículo EventWaitHandle.For more information, see the EventWaitHandle article. Para la referencia de API, consulte EventWaitHandle, AutoResetEvent, ManualResetEvent y ManualResetEventSlim.For the API reference, see EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim.

Clase CountdownEventCountdownEvent class

La clase System.Threading.CountdownEvent representa un evento que se establece cuando su recuento es cero.The System.Threading.CountdownEvent class represents an event that becomes set when its count is zero. Mientras CountdownEvent.CurrentCount sea mayor que cero, un subproceso que llama a CountdownEvent.Wait está bloqueado.While CountdownEvent.CurrentCount is greater than zero, a thread that calls CountdownEvent.Wait is blocked. Llame a CountdownEvent.Signal para reducir el recuento de un evento.Call CountdownEvent.Signal to decrement an event's count.

En contraposición a ManualResetEvent o ManualResetEventSlim, que puede usar para desbloquear varios subprocesos con una señal de un subproceso, puede usar CountdownEvent para desbloquear uno o varios subprocesos con las señales de varios subprocesos.In contrast to ManualResetEvent or ManualResetEventSlim, which you can use to unblock multiple threads with a signal from one thread, you can use CountdownEvent to unblock one or more threads with signals from multiple threads.

Para más información, vea el artículo CountdownEvent y la referencia de API CountdownEvent.For more information, see the CountdownEvent article and the CountdownEvent API reference.

Barrier (clase)Barrier class

La clase System.Threading.Barrier representa una barrera de ejecución de subprocesos.The System.Threading.Barrier class represents a thread execution barrier. Un subproceso que llama al método Barrier.SignalAndWait indica que ha alcanzado la barrera y espera hasta que otros subprocesos participantes alcancen la barrera.A thread that calls the Barrier.SignalAndWait method signals that it reached the barrier and waits until other participant threads reach the barrier. Cuando todos los subprocesos participantes alcancen la barrera, continúan y la barrera se restablece y se puede volver a usar.When all participant threads reach the barrier, they proceed and the barrier is reset and can be used again.

Puede usar Barrier cuando uno o más subprocesos requieren los resultados de otros subprocesos antes de continuar con la siguiente fase del cálculo.You might use Barrier when one or more threads require the results of other threads before proceeding to the next computation phase.

Para más información, vea el artículo Barrier y la referencia de API Barrier.For more information, see the Barrier article and the Barrier API reference.

Interlocked (clase)Interlocked class

La clase System.Threading.Interlocked proporciona métodos estáticos que realizan operaciones atómicas simples en una variable.The System.Threading.Interlocked class provides static methods that perform simple atomic operations on a variable. Esas operaciones atómicas incluyen la adición, el incremento y el decremento, el intercambio y el intercambio condicional que depende de una comparación, y la operación de lectura de un valor entero de 64 bits.Those atomic operations include addition, increment and decrement, exchange and conditional exchange that depends on a comparison, and read operation of a 64-bit integer value.

Para más información, vea la referencia de API Interlocked.For more information, see the Interlocked API reference.

SpinWait (estructura)SpinWait structure

La estructura System.Threading.SpinWait proporciona compatibilidad para la espera basada en ciclos.The System.Threading.SpinWait structure provides support for spin-based waiting. Puede que le interese utilizarla cuando un subproceso tiene que esperar a que se señalice un evento o se cumpla una condición, pero cuando el tiempo de espera real deba ser menor que el tiempo de espera necesario usando un identificador de espera o bloqueando de otro modo el subproceso.You might want to use it when a thread has to wait for an event to be signaled or a condition to be met, but when the actual wait time is expected to be less than the waiting time required by using a wait handle or by otherwise blocking the thread. Si usa SpinWait, puede especificar un breve período de tiempo para girar durante la espera y después ceder (por ejemplo, esperando o entrando en modo de suspensión) solo si la condición no se cumplió en el tiempo especificado.By using SpinWait, you can specify a short period of time to spin while waiting, and then yield (for example, by waiting or sleeping) only if the condition was not met in the specified time.

Para más información, vea el artículo SpinWait y la referencia de API SpinWait.For more information, see the SpinWait article and the SpinWait API reference.

Vea tambiénSee also