Funciones wait

Las funciones de espera permiten que un subproceso bloquee su propia ejecución. Las funciones wait no devuelven hasta que se cumplen los criterios especificados. El tipo de función wait determina el conjunto de criterios usados. Cuando se llama a una función de espera, comprueba si se han cumplido los criterios de espera. Si no se han cumplido los criterios, el subproceso que realiza la llamada entra en el estado de espera hasta que se cumplan las condiciones de los criterios de espera o transcurrido el intervalo de tiempo de espera especificado.

Funciones wait de un solo objeto

Las funciones SignalObjectAndWait, WaitForSingleObject y WaitForSingleObjectEx requieren un identificador para un objeto de sincronización. Estas funciones devuelven cuando se produce una de las siguientes acciones:

  • El objeto especificado está en estado señalado.
  • El intervalo de tiempo de espera transcurre. El intervalo de tiempo de espera se puede establecer en INFINITE para especificar que la espera no agotará el tiempo de espera.

La función SignalObjectAndWait permite que el subproceso que llama establezca de forma atómica el estado de un objeto en señalizado y espere a que el estado de otro objeto se establezca en señalizado.

Funciones de espera de varios objetos

Las funciones WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjects y MsgWaitForMultipleObjectsEx permiten al subproceso de llamada especificar una matriz que contenga uno o varios identificadores de objeto de sincronización. Estas funciones devuelven cuando se produce una de las siguientes acciones:

  • El estado de cualquiera de los objetos especificados se establece en señalizado o los estados de todos los objetos se han establecido en señalizado. Puede controlar si se usará uno o todos los estados en la llamada de función.
  • El intervalo de tiempo de espera transcurre. El intervalo de tiempo de espera se puede establecer en INFINITE para especificar que la espera no agotará el tiempo de espera.

La función MsgWaitForMultipleObjects y MsgWaitForMultipleObjectsEx permite especificar objetos de evento de entrada en la matriz de identificadores de objetos. Esto se hace cuando se especifica el tipo de entrada que se va a esperar en la cola de entrada del subproceso. Por ejemplo, un subproceso podría usar MsgWaitForMultipleObjects para bloquear su ejecución hasta que el estado de un objeto especificado se haya establecido en señalizado y haya entradas del mouse disponibles en la cola de entrada del subproceso. El subproceso puede usar la función GetMessage o PeekMessageA o PeekMessageW para recuperar la entrada.

Al esperar a que se indiquen los estados de todos los objetos, estas funciones de varios objetos no modifican los estados de los objetos especificados hasta que se hayan establecido los estados de todos los objetos. Por ejemplo, el estado de un objeto de exclusión mutua se puede señalar, pero el subproceso que realiza la llamada no obtiene la propiedad hasta que los estados de los demás objetos especificados en la matriz también se han establecido en señalizado. Mientras tanto, algún otro subproceso puede obtener la propiedad del objeto de exclusión mutua, estableciendo así su estado en sin signo.

Al esperar a que el estado de un único objeto se establezca en señalizado, estas funciones de varios objetos comprueban los identificadores de la matriz en orden a partir del índice 0, hasta que se señale uno de los objetos. Si se señalizan varios objetos, la función devuelve el índice del primer identificador de la matriz cuyo objeto se señalizó.

Funciones de espera alertables

Las funciones MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsEx y WaitForSingleObjectEx difieren de las demás funciones de espera en que, opcionalmente, pueden realizar una operación de espera alertable. En una operación de espera alertable, la función puede devolver cuando se cumplen las condiciones especificadas, pero también puede devolver si el sistema pone en cola una rutina de finalización de E/S o un APC para su ejecución mediante el subproceso en espera. Para obtener más información sobre las operaciones de espera alertables y las rutinas de finalización de E/S, vea Sincronización y entrada y salida superpuestas. Para obtener más información sobre las API, vea Llamadas a procedimientos asincrónicos.

Funciones de espera registradas

La función RegisterWaitForSingleObject difiere de las demás funciones de espera en que una conversación del grupo de subprocesos realiza la operación de espera. Cuando se cumplen las condiciones especificadas, un subproceso de trabajo ejecuta la función de devolución de llamada desde el grupo de subprocesos.

De forma predeterminada, una operación de espera registrada es una operación de espera múltiple. El sistema restablece el temporizador cada vez que se señala el evento (o el intervalo de tiempo de espera transcurrido) hasta que se llama a la función UnregisterWaitEx para cancelar la operación. Para especificar que una operación de espera solo se debe ejecutar una vez, establezca el parámetro dwFlags de RegisterWaitForSingleObjecten WT_EXECUTEONLYONCE.

Si el subproceso llama a funciones que usan API, establezca el parámetro dwFlags de RegisterWaitForSingleObjecten WT_EXECUTEINPERSISTENTTHREAD.

Esperando una dirección

Un subproceso puede usar la función WaitOnAddress para esperar a que el valor de una dirección de destino cambie de algún valor no deseado a cualquier otro valor. Esto permite a los subprocesos esperar a que un valor cambie sin tener que girar ni controlar los problemas de sincronización que pueden surgir cuando el subproceso captura un valor no deseado, pero el valor cambia antes de que el subproceso pueda esperar.

WaitOnAddress devuelve cuando el código que modifica el valor de destino indica el cambio llamando a WakeByAddressSingle para reactivar un único subproceso en espera o WakeByAddressAll para reactivar todos los subprocesos en espera. Si se especifica un intervalo de tiempo de espera con WaitOnAddress y ningún subproceso llama a una función de reactivación, la función devuelve cuando transcurre el intervalo de tiempo de espera. Si no se especifica ningún intervalo de tiempo de espera, el subproceso espera indefinidamente.

Funciones de espera e intervalos de tiempo de espera

La precisión del intervalo de tiempo de espera especificado depende de la resolución del reloj del sistema. El reloj del sistema "tics" a una velocidad constante. Si el intervalo de tiempo de espera es menor que la resolución del reloj del sistema, la espera puede agotarse en menos del tiempo especificado. Si el intervalo de tiempo de espera es mayor que un tic pero menor que dos, la espera puede estar entre uno y dos tics, etc.

Para aumentar la precisión del intervalo de tiempo de espera de las funciones de espera, llame a la función timeGetDevCaps para determinar la resolución mínima admitida del temporizador y la función timeBeginPeriod para establecer la resolución del temporizador en su mínimo. Tenga cuidado al llamar a timeBeginPeriod, ya que las llamadas frecuentes pueden afectar significativamente al reloj del sistema, el uso de energía del sistema y el programador. Si llama a timeBeginPeriod, llámelo una vez al principio de la aplicación y asegúrese de llamar a la función timeEndPeriod al final de la aplicación.

Funciones de espera y objetos de sincronización

Las funciones de espera pueden modificar los estados de algunos tipos de objetos de sincronización. La modificación solo se produce para el objeto u objetos cuyo estado señalado ha provocado que la función devuelva. Las funciones de espera pueden modificar los estados de los objetos de sincronización de la siguiente manera:

  • El recuento de un objeto de semáforo disminuye en uno y el estado del semáforo se establece en no asignado si su recuento es cero.
  • Los estados de exclusión mutua, evento de restablecimiento automático y objetos de notificación de cambios se establecen en no asignados.
  • El estado de un temporizador de sincronización se establece en sin signo.
  • Los estados del evento de restablecimiento manual, el temporizador de restablecimiento manual, el proceso, el subproceso y los objetos de entrada de la consola no se ven afectados por una función de espera.

Funciones de espera y creación de Windows

Debe tener cuidado al usar las funciones de espera y el código que crea ventanas directa o indirectamente. Si un subproceso crea ventanas, debe procesar los mensajes. Las difusiones de mensajes se envían a todas las ventanas del sistema. Si tiene un subproceso que usa una función de espera sin intervalo de tiempo de espera, el sistema interbloqueo. Dos ejemplos de código que crea indirectamente ventanas son DDE y la función CoInitialize . Por lo tanto, si tiene un subproceso que crea ventanas, use MsgWaitForMultipleObjects o MsgWaitForMultipleObjectsEx, en lugar de las demás funciones de espera.