Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Actualización: noviembre 2007
Las aplicaciones multiproceso suelen utilizar controladores de espera y objetos de supervisión para sincronizar múltiples subprocesos. Estas secciones explican cómo utilizar las siguientes clases de .NET Framework al sincronizar subprocesos: AutoResetEvent, Interlocked, ManualResetEvent, Monitor, Mutex, ReaderWriterLock, Timer, WaitHandle.
Controladores de espera
Los controladores de espera son objetos que indican el estado de un subproceso a otro subproceso. Los subprocesos pueden utilizar controladores de espera para notificar a otros subprocesos que necesitan acceso exclusivo a un recurso. Entonces, otros subprocesos deben esperar para utilizar este recurso, hasta que el controlador deje de estar en uso. Los controladores de espera tienen dos estados, señalizado y no señalizado. Un controlador de espera que no es propiedad de ningún subproceso está en el estado señalizado. Un controlador de espera que es propiedad de un subproceso está en el estado no señalizado.
Para solicitar la propiedad de un controlador de espera, los subprocesos llaman a uno de los métodos de espera: WaitOne, WaitAny o WaitAll. Los métodos de espera son llamadas de bloqueo similares al método Join de un subproceso individual:
Si ningún otro subproceso es propietario del controlador de espera, la llamada devuelve inmediatamente True, el estado del controlador de espera cambia a no señalizado y el subproceso propietario del controlador de espera continúa ejecutándose.
Si un subproceso llama a uno de los métodos de espera de un controlador de espera, pero el controlador de espera es propiedad de otro subproceso, el subproceso que hace la llamada espere durante un tiempo específico (si se especificó un tiempo de espera) o espere indefinidamente (si no se especificó ningún tiempo de espera) hasta que el otro subproceso libere el controlador de espera. Si se especificó un tiempo de espera y el controlador de espera se libera antes de que transcurra ese tiempo, la llamada devuelve True. En caso contrario, la llamada de espera devuelve False y el subproceso que hace la llamada continúa ejecutándose.
Los subprocesos propietarios de un controlador de espera llaman al método Set cuando terminan o cuando ya no necesitan el controlador de espera. Otros subprocesos pueden restablecer el estado de un controlador de espera al estado no señalizado llamando al método Reset o llamado a WaitOne, WaitAny o WaitAll, y esperando con éxito a que un subproceso llame a Set. El sistema restablece automáticamente los controladores AutoResetEvent al estado no señalizado una vez liberado un subproceso de espera. Si no hay subprocesos en espera, el objeto del evento sigue teniendo el estado señalizado.
Hay tres tipos de controladores de espera usados frecuentemente en Visual Basic: los objetos de exclusión mutua (mutex), ManualResetEvent y AutoResetEvent. Los dos últimos suelen conocerse como eventos de sincronización.
Objetos de exclusión mutua (Mutex)
Los objetos de exclusión mutua son objetos de sincronización que sólo pueden ser propiedad de un único subproceso a la vez. El nombre "mutex" proviene del hecho de que la propiedad de estos objetos es mutuamente exclusiva. Los subprocesos solicitan la propiedad del objeto mutex cuando necesitan acceso a un recurso. Dado que sólo un subproceso puede poseer un objeto mutex en cualquier momento dado, los demás subprocesos deben esperar a poseer un objeto mutex antes de utilizar el recurso.
El método WaitOne hace que un subproceso que realiza una llamada espere la propiedad de un objeto mutex. Si un subproceso termina normalmente mientras es propietario de un objeto mutex, el estado del objeto mutex se establece en señalizado, y la propiedad pasa al siguiente subproceso en espera.
Eventos de sincronización
Los eventos de sincronización se utilizan para notificar a otros subprocesos que ha ocurrido algo o que un recurso está disponible. A pesar de que el término incluya la palabra "evento", los eventos de sincronización son diferentes de otros eventos de Visual Basic: realmente esperan los controladores. Al igual que otros controladores de espera, los eventos de sincronización tienen dos estados, señalizado y no señalizado.
Los subprocesos que llaman a uno de los métodos de espera de un evento de sincronización deben esperar hasta que otro subproceso señalice el evento mediante una llamada al método Set. Hay dos clases de eventos de sincronización: ManualResetEvent y AutoResetEvent.
Los subprocesos establecen el estado de las instancias de ManualResetEvent en señalizado mediante el método Set. Los subprocesos establecen el estado de las instancias ManualResetEvent en no señalizado mediante el método Reset o el control vuelve a una llamada de espera WaitOne.
También es posible establecer en señalizado el estado de las instancias de la clase AutoResetEvent mediante Set, pero vuelven automáticamente al estado no señalizado tan pronto como un subproceso en espera recibe la notificación de que el evento ha pasado a estar señalizado.
Objetos de supervisión y SyncLock
Los objetos de supervisión se utilizan para garantizar que un bloque de código funciona sin verse interrumpido por el código que se ejecuta en otros subprocesos. En otras palabras, el código de otros subprocesos no puede ejecutarse hasta que ha terminado el código del bloque de código sincronizado.
Suponga, por ejemplo, que tiene un programa que lee datos de forma repetida y asincrónica y muestra los resultados. Con los sistemas operativos que utilizan la multitarea preferente, un subproceso en ejecución puede verse interrumpido por el sistema operativo para dar más tiempo a que se ejecute otro subproceso. Sin sincronización, es posible obtener una vista parcialmente actualizada de los datos si el objeto que representa los datos es modificado por otro subproceso mientras se muestran los datos. Los objetos de supervisión garantizan que una sección del código se ejecutará sin interrupción. Visual Basic proporciona las instrucciones SyncLock y End SyncLock para simplificar el acceso a los objetos de supervisión. Visual C# utiliza la palabra clave Lock de la misma manera.
Nota: |
|---|
El acceso a un objeto está bloqueado únicamente si el código que está obteniendo acceso a él está contenido en un bloque SyncLock en la misma instancia de objeto. |
Para obtener información acerca de la instrucción SyncLock, vea SyncLock (Instrucción).
Clase Interlocked
Puede utilizar los métodos de la clase Interlocked para evitar problemas que pueden producirse cuando varios subprocesos intentan actualizar o comparar simultáneamente el mismo valor. Los métodos de esta clase permiten incrementar, reducir, intercambiar y comparar valores, de forma segura, desde cualquier subproceso El ejemplo siguiente muestra cómo utilizar el método Increment para incrementar una variable compartida por procedimientos que se ejecutan en subprocesos independientes.
Sub ThreadA(ByRef IntA As Integer)
System.Threading.Interlocked.Increment(IntA)
End Sub
Sub ThreadB(ByRef IntA As Integer)
System.Threading.Interlocked.Increment(IntA)
End Sub
Bloqueos ReaderWriterLock
En algunos casos, quizá desee bloquear un recurso sólo mientras se están escribiendo los datos y permitir que múltiples clientes puedan leer datos simultáneamente cuando no se estén actualizando los datos. La clase ReaderWriterLock fuerza el acceso exclusivo a un recurso mientras hay un subproceso modificando el recurso, pero permite el acceso no exclusivo al leer el recurso. Los bloqueos de ReaderWriter son una alternativa útil a los bloqueos exclusivos que hacen esperar a otros subprocesos, incluso cuando esos subprocesos no necesitan actualizar datos.
Interbloqueos
La sincronización de subprocesos resulta de un valor incalculable en aplicaciones multiproceso, pero siempre existe el peligro de crear un deadlock, en el que varios subprocesos están esperando unos a otros y la aplicación se bloquea. Un interbloqueo es una situación análoga a otra en la que hay automóviles parados en un cruce con cuatro señales de stop y cada uno de los conductores está esperando a que los otros se pongan en marcha. Evitar los interbloqueos es importante; la clave está en una cuidadosa planificación. A menudo es posible prevenir situaciones de interbloqueo mediante la creación de diagramas de las aplicaciones multiproceso, antes de empezar a escribir código.
Vea también
Conceptos
Subprocesamiento múltiple avanzado con Visual Basic
Nota: