Sincronización de subprocesos múltiples: objeto de kernel de temporizador awaitable

1. Introducción

Se disparan en un momento específico, o cada cierto tiempo. Suelen utilizarse para realizar alguna operación en un momento determinado.

HANDLE CreateWaitableTimer
(
   PSECURITY_ATTRIBUTES psa,
   BOOL fManualReset,
   PCTSTR pszName
);
  • psa: Puntero a la estructura SECURITY_ATTRIBUTES.
  • fManualReset: le dice al sistema si debe crear un temporizador de reinicio manual (VERDADERO) o un temporizador de evento de reinicio automático (FALSO).
  • pszName: el nombre del objeto.

  • Cuando se señala un temporizador de restablecimiento manual, todos los subprocesos que esperan en ese temporizador se convierten en subprocesos programables.
  • Una señal de temporizador de reinicio automático cuando solo se puede programar un subproceso en espera.

Un proceso llama a la función OpenWaitableTimer para obtener un identificador de un temporizador de espera existente, que está asociado con el proceso actual.

HANDLE OpenWaitableTimer
(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName
);

En el momento de la creación, los objetos de temporizador de espera siempre se crean en un estado no notificado (a diferencia de los objetos de evento, que nos permiten especificar). Cuando queramos activar el temporizador, debemos llamar a SetWaitableTimer.

BOOL SetWaitableTimer
(
   HANDLE hTimer,
   const LARGE_INTEGER *pDueTime,
   LONG lPeriod,
   PTIMERAPCROUTINE pfnCompletionRoutine,
   PVOID pvArgToCompletionRoutine,
   BOOL fResume
);
  • El parámetro hTimer se utiliza para indicar el temporizador que desea configurar.
  • Los dos parámetros pDueTime y lPeriod se usan juntos. El parámetro PDueTimer se usa para indicar cuándo el temporizador debe informar la hora por primera vez, y el parámetro lPeriod se usa para indicar cuánto tiempo debe informar el temporizador después de eso.
  • fReanudar: se puede usar en computadoras que admitan suspender y reanudar. Normalmente puede pasar FALSO para este parámetro.

2. Ejemplo

int main()
{
    HANDLE hTimer = NULL;
    LARGE_INTEGER liDueTime;

    liDueTime.QuadPart = -100000000LL;

    // Create an unnamed waitable timer.
    hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
    if (NULL == hTimer)
    {
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
        return 1;
    }

    printf("Waiting for 10 seconds...\n");

    // Set a timer to wait for 10 seconds.
    if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
    {
        printf("SetWaitableTimer failed (%d)\n", GetLastError());
        return 2;
    }

    // Wait for the timer.

    if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
        printf("WaitForSingleObject failed (%d)\n", GetLastError());
    else printf("Timer was signaled.\n");

    return 0;
}

Resultado de ejecución: espere 10 segundos para finalizar

Al llamar a SetWaitableTimer, además de especificar un tiempo absoluto cuando el temporizador se activa por primera vez, también podemos especificar un tiempo relativo. Simplemente pase un valor negativo en el parámetro PDueTimer. El valor pasado debe ser un múltiplo entero de 100 nanosegundos.

1s = 1000ms = 1000000µs = 100000000ns

Por lo general, es posible que desee un temporizador que suene una vez, donde solo suene una vez y nunca suene a partir de entonces. Para hacer esto, simplemente pase 0 para el parámetro lPeriod. Luego, puede llamar a la función CloseHandle para cerrar el temporizador, o volver a llamar a la función SetWaitableTimer para restablecer el tiempo y establecer una nueva condición para que siga.

Supongo que te gusta

Origin blog.csdn.net/wzz953200463/article/details/127271559
Recomendado
Clasificación