Semaphore Clase
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Limita el número de subprocesos que pueden acceder simultáneamente a un recurso o grupo de recursos.
public ref class Semaphore sealed : System::Threading::WaitHandle
public sealed class Semaphore : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(false)>]
type Semaphore = class
inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
- Herencia
- Herencia
- Atributos
Ejemplos
En el ejemplo de código siguiente se crea un semáforo con un recuento máximo de tres y un recuento inicial de cero. En el ejemplo se inician cinco subprocesos, que bloquean la espera del semáforo. El subproceso principal usa la Release(Int32) sobrecarga del método para aumentar el recuento de semáforos a su máximo, lo que permite que tres subprocesos entren en el semáforo. Cada subproceso usa el Thread.Sleep método para esperar un segundo, simular el trabajo y, a continuación, llama a la sobrecarga del Release() método para liberar el semáforo. Cada vez que se libera el semáforo, se muestra el recuento de semáforos anterior. Los mensajes de la consola realizan un seguimiento del semáforo. El intervalo de trabajo simulado aumenta ligeramente para cada subproceso para facilitar la lectura de la salida.
using System;
using System.Threading;
public class Example
{
// A semaphore that simulates a limited resource pool.
//
private static Semaphore _pool;
// A padding interval to make the output more orderly.
private static int _padding;
public static void Main()
{
// Create a semaphore that can satisfy up to three
// concurrent requests. Use an initial count of zero,
// so that the entire semaphore count is initially
// owned by the main program thread.
//
_pool = new Semaphore(initialCount: 0, maximumCount: 3);
// Create and start five numbered threads.
//
for(int i = 1; i <= 5; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Worker));
// Start the thread, passing the number.
//
t.Start(i);
}
// Wait for half a second, to allow all the
// threads to start and to block on the semaphore.
//
Thread.Sleep(500);
// The main thread starts out holding the entire
// semaphore count. Calling Release(3) brings the
// semaphore count back to its maximum value, and
// allows the waiting threads to enter the semaphore,
// up to three at a time.
//
Console.WriteLine("Main thread calls Release(3).");
_pool.Release(releaseCount: 3);
Console.WriteLine("Main thread exits.");
}
private static void Worker(object num)
{
// Each worker thread begins by requesting the
// semaphore.
Console.WriteLine("Thread {0} begins " +
"and waits for the semaphore.", num);
_pool.WaitOne();
// A padding interval to make the output more orderly.
int padding = Interlocked.Add(ref _padding, 100);
Console.WriteLine("Thread {0} enters the semaphore.", num);
// The thread's "work" consists of sleeping for
// about a second. Each thread "works" a little
// longer, just to make the output more orderly.
//
Thread.Sleep(1000 + padding);
Console.WriteLine("Thread {0} releases the semaphore.", num);
Console.WriteLine("Thread {0} previous semaphore count: {1}",
num, _pool.Release());
}
}
Imports System.Threading
Public Class Example
' A semaphore that simulates a limited resource pool.
'
Private Shared _pool As Semaphore
' A padding interval to make the output more orderly.
Private Shared _padding As Integer
<MTAThread> _
Public Shared Sub Main()
' Create a semaphore that can satisfy up to three
' concurrent requests. Use an initial count of zero,
' so that the entire semaphore count is initially
' owned by the main program thread.
'
_pool = New Semaphore(0, 3)
' Create and start five numbered threads.
'
For i As Integer = 1 To 5
Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
'Dim t As New Thread(AddressOf Worker)
' Start the thread, passing the number.
'
t.Start(i)
Next i
' Wait for half a second, to allow all the
' threads to start and to block on the semaphore.
'
Thread.Sleep(500)
' The main thread starts out holding the entire
' semaphore count. Calling Release(3) brings the
' semaphore count back to its maximum value, and
' allows the waiting threads to enter the semaphore,
' up to three at a time.
'
Console.WriteLine("Main thread calls Release(3).")
_pool.Release(3)
Console.WriteLine("Main thread exits.")
End Sub
Private Shared Sub Worker(ByVal num As Object)
' Each worker thread begins by requesting the
' semaphore.
Console.WriteLine("Thread {0} begins " _
& "and waits for the semaphore.", num)
_pool.WaitOne()
' A padding interval to make the output more orderly.
Dim padding As Integer = Interlocked.Add(_padding, 100)
Console.WriteLine("Thread {0} enters the semaphore.", num)
' The thread's "work" consists of sleeping for
' about a second. Each thread "works" a little
' longer, just to make the output more orderly.
'
Thread.Sleep(1000 + padding)
Console.WriteLine("Thread {0} releases the semaphore.", num)
Console.WriteLine("Thread {0} previous semaphore count: {1}", _
num, _
_pool.Release())
End Sub
End Class
Comentarios
Use la clase para controlar el Semaphore acceso a un grupo de recursos. Los subprocesos escriben el semáforo llamando al WaitOne método , que se hereda de la WaitHandle clase y liberan el semáforo llamando al Release método .
El recuento de un semáforo se disminuye cada vez que un subproceso entra en el semáforo e incrementa cuando un subproceso libera el semáforo. Cuando el recuento es cero, las solicitudes posteriores se bloquean hasta que otros subprocesos liberan el semáforo. Cuando todos los subprocesos han liberado el semáforo, el recuento se encuentra en el valor máximo especificado cuando se creó el semáforo.
No hay ningún orden garantizado, como FIFO o LIFO, en el que los subprocesos bloqueados entran en el semáforo.
Un subproceso puede escribir el semáforo varias veces llamando al WaitOne método repetidamente. Para liberar algunas o todas estas entradas, el subproceso puede llamar a la sobrecarga del método sin Release() parámetros varias veces, o bien puede llamar a la sobrecarga del Release(Int32) método que especifica el número de entradas que se van a liberar.
La Semaphore clase no aplica la identidad del subproceso en las llamadas a WaitOne o Release. Es responsabilidad del programador asegurarse de que los subprocesos no liberan el semáforo demasiadas veces. Por ejemplo, supongamos que un semáforo tiene un recuento máximo de dos y que el hilo A y el hilo B acceden al semáforo. Si un error de programación en el subproceso B hace que llame Release dos veces, ambas llamadas se realizan correctamente. El recuento del semáforo está lleno y cuando el subproceso A finalmente llama a Release, se genera SemaphoreFullException.
Los semáforos son de dos tipos: semáforos locales y semáforos del sistema con nombre. Si crea un Semaphore objeto mediante un constructor que acepta un nombre, está asociado a un semáforo del sistema operativo de ese nombre. Los semáforos del sistema con nombre son visibles en todo el sistema operativo y se pueden usar para sincronizar las actividades de los procesos. Puede crear varios Semaphore objetos que representen el mismo semáforo del sistema con nombre y puede usar el OpenExisting método para abrir un semáforo del sistema con nombre existente.
Solo existe un semáforo local dentro del proceso. Puede ser utilizado por cualquier subproceso del proceso que tenga una referencia al objeto local Semaphore . Cada Semaphore objeto es un semáforo local independiente.
Caution
De forma predeterminada, un semáforo con nombre no está restringido al usuario que lo creó. Otros usuarios pueden abrir y usar el semáforo, incluida la interferencia con el semáforo al adquirir el semáforo varias veces y no liberarlo. Para restringir el acceso a usuarios específicos, puede usar una sobrecarga de constructor o SemaphoreAcl pasar un SemaphoreSecurity al crear el semáforo con nombre. Evite usar semáforos con nombre sin restricciones de acceso en sistemas que podrían tener usuarios que no son de confianza que ejecuten código.
Constructores
| Nombre | Description |
|---|---|
| Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity) |
Inicializa una nueva instancia de la Semaphore clase , especificando el número inicial de entradas y el número máximo de entradas simultáneas, especificando opcionalmente el nombre de un objeto semáforo del sistema, especificando una variable que recibe un valor que indica si se creó un nuevo semáforo del sistema y especificando el control de acceso de seguridad para el semáforo del sistema. |
| Semaphore(Int32, Int32, String, Boolean) |
Inicializa una nueva instancia de la Semaphore clase , especificando el número inicial de entradas y el número máximo de entradas simultáneas, especificando opcionalmente el nombre de un objeto de semáforo del sistema y especificando una variable que recibe un valor que indica si se creó un nuevo semáforo del sistema. |
| Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean) |
Inicializa una nueva instancia de la Semaphore clase , especificando el número inicial de entradas y el número máximo de entradas simultáneas, especificando opcionalmente el nombre de un objeto de semáforo del sistema y las opciones para establecer el ámbito de usuario y el acceso al ámbito de sesión, y especificando una variable que recibe un valor que indica si se creó un nuevo semáforo del sistema. |
| Semaphore(Int32, Int32, String, NamedWaitHandleOptions) |
Inicializa una nueva instancia de la Semaphore clase , especificando el número inicial de entradas y el número máximo de entradas simultáneas y, opcionalmente, especificando el nombre de un objeto de semáforo del sistema y las opciones para establecer el ámbito de usuario y el acceso de ámbito de sesión. |
| Semaphore(Int32, Int32, String) |
Inicializa una nueva instancia de la Semaphore clase , especificando el número inicial de entradas y el número máximo de entradas simultáneas y, opcionalmente, especificando el nombre de un objeto de semáforo del sistema. |
| Semaphore(Int32, Int32) |
Inicializa una nueva instancia de la Semaphore clase , especificando el número inicial de entradas y el número máximo de entradas simultáneas. |
Campos
| Nombre | Description |
|---|---|
| WaitTimeout |
Indica que se ha agotado el tiempo de espera de una WaitAny(WaitHandle[], Int32, Boolean) operación antes de que se señalizara cualquiera de los identificadores de espera. Este campo es constante. (Heredado de WaitHandle) |
Propiedades
| Nombre | Description |
|---|---|
| Handle |
Obsoletos.
Obsoletos.
Obtiene o establece el identificador del sistema operativo nativo. (Heredado de WaitHandle) |
| SafeWaitHandle |
Obtiene o establece el identificador del sistema operativo nativo. (Heredado de WaitHandle) |
Métodos
| Nombre | Description |
|---|---|
| Close() |
Libera todos los recursos mantenidos por el actual WaitHandle. (Heredado de WaitHandle) |
| CreateObjRef(Type) |
Crea un objeto que contiene toda la información pertinente necesaria para generar un proxy usado para comunicarse con un objeto remoto. (Heredado de MarshalByRefObject) |
| Dispose() |
Libera todos los recursos usados por la instancia actual de la WaitHandle clase . (Heredado de WaitHandle) |
| Dispose(Boolean) |
Cuando se reemplaza en una clase derivada, libera los recursos no administrados usados por WaitHandley, opcionalmente, libera los recursos administrados. (Heredado de WaitHandle) |
| Equals(Object) |
Determina si el objeto especificado es igual al objeto actual. (Heredado de Object) |
| GetAccessControl() |
Obtiene la seguridad del control de acceso para un semáforo del sistema con nombre. |
| GetHashCode() |
Actúa como función hash predeterminada. (Heredado de Object) |
| GetLifetimeService() |
Obsoletos.
Recupera el objeto de servicio de duración actual que controla la directiva de duración de esta instancia. (Heredado de MarshalByRefObject) |
| GetType() |
Obtiene el Type de la instancia actual. (Heredado de Object) |
| InitializeLifetimeService() |
Obsoletos.
Obtiene un objeto de servicio de duración para controlar la directiva de duración de esta instancia. (Heredado de MarshalByRefObject) |
| MemberwiseClone() |
Crea una copia superficial del Objectactual. (Heredado de Object) |
| MemberwiseClone(Boolean) |
Crea una copia superficial del objeto actual MarshalByRefObject . (Heredado de MarshalByRefObject) |
| OpenExisting(String, NamedWaitHandleOptions) |
Abre el semáforo con nombre especificado, si ya existe. Si las opciones se establecen solo en el usuario actual, los controles de acceso del objeto se comprueban para el usuario que llama. |
| OpenExisting(String, SemaphoreRights) |
Abre el semáforo con nombre especificado, si ya existe, con el acceso de seguridad deseado. |
| OpenExisting(String) |
Abre el semáforo con nombre especificado, si ya existe. |
| Release() |
Sale del semáforo y devuelve el recuento anterior. |
| Release(Int32) |
Sale del semáforo un número especificado de veces y devuelve el recuento anterior. |
| SetAccessControl(SemaphoreSecurity) |
Establece la seguridad del control de acceso para un semáforo del sistema con nombre. |
| ToString() |
Devuelve una cadena que representa el objeto actual. (Heredado de Object) |
| TryOpenExisting(String, NamedWaitHandleOptions, Semaphore) |
Abre el semáforo con nombre especificado, si ya existe y devuelve un valor que indica si la operación se realizó correctamente. Si las opciones se establecen solo en el usuario actual, los controles de acceso del objeto se comprueban para el usuario que llama. |
| TryOpenExisting(String, Semaphore) |
Abre el semáforo con nombre especificado, si ya existe y devuelve un valor que indica si la operación se realizó correctamente. |
| TryOpenExisting(String, SemaphoreRights, Semaphore) |
Abre el semáforo con nombre especificado, si ya existe, con el acceso de seguridad deseado y devuelve un valor que indica si la operación se realizó correctamente. |
| WaitOne() |
Bloquea el subproceso actual hasta que el actual WaitHandle recibe una señal. (Heredado de WaitHandle) |
| WaitOne(Int32, Boolean) |
Bloquea el subproceso actual hasta que el actual WaitHandle recibe una señal, usando un entero de 32 bits con signo para especificar el intervalo de tiempo y especificar si se sale del dominio de sincronización antes de la espera. (Heredado de WaitHandle) |
| WaitOne(Int32) |
Bloquea el subproceso actual hasta que el actual WaitHandle recibe una señal, utilizando un entero de 32 bits con signo para especificar el intervalo de tiempo en milisegundos. (Heredado de WaitHandle) |
| WaitOne(TimeSpan, Boolean) |
Bloquea el subproceso actual hasta que la instancia actual recibe una señal, utilizando para TimeSpan especificar el intervalo de tiempo y especificando si se sale del dominio de sincronización antes de la espera. (Heredado de WaitHandle) |
| WaitOne(TimeSpan) |
Bloquea el subproceso actual hasta que la instancia actual recibe una señal, utilizando para TimeSpan especificar el intervalo de tiempo. (Heredado de WaitHandle) |
Implementaciones de interfaz explícitas
| Nombre | Description |
|---|---|
| IDisposable.Dispose() |
Esta API admite la infraestructura de producto y no está pensada para usarse directamente en el código. Libera todos los recursos usados por .WaitHandle (Heredado de WaitHandle) |
Métodos de extensión
| Nombre | Description |
|---|---|
| GetAccessControl(Semaphore) |
Devuelve los descriptores de seguridad para el especificado |
| GetSafeWaitHandle(WaitHandle) |
Obtiene el identificador seguro de un identificador de espera de sistema operativo nativo. |
| SetAccessControl(Semaphore, SemaphoreSecurity) |
Establece los descriptores de seguridad para el semáforo especificado. |
| SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Establece un identificador seguro para un identificador de espera de sistema operativo nativo. |
Se aplica a
Seguridad para subprocesos
Este tipo es seguro para subprocesos.