Event Object Notification

Windows Mobile SupportedWindows Embedded CE Supported

9/8/2008

Windows Embedded CE usa objetos evento para o seguinte completo tarefas:

  • Notificar um segmento quando para executar sua tarefa.
  • Indica que um evento ocorreu.

De exemplo, um segmento que grava uma reserva redefine o objeto evento para um sinalizado estado Quando ele terminar de escrita.

Usando um objeto evento para notificar o segmento que sua tarefa estiver concluída, o segmento pode imediatamente iniciar Executar outras tarefas.

Para criar um objeto evento, chamar a função CreateEvent.

O seguinte mostra exemplo de código o CreateEvent função protótipo:

HANDLE CreateEvent (NULL, BOOL bManualReset, BOOL bInitialState, LPTSTR lpName);

A seguinte tabela descreve os parâmetros.

Parâmetro Descrição

lpName

Especifica o nome do objeto de evento ou para deixar o objeto sem nome.

bManualReset

Especifica se o objeto evento redefine próprio de um sinalizado estado para um não sinalizado estado, ou se ele requer um redefinir manual.

bInitialState

Especifica se o objeto evento é criado no sinalizado ou não sinalizado estado.

Eventos nomeados podem ser compartilhados com outros processos. Segmentos em outros processos podem aberto um identificador para um objeto existente evento especificando seu nome em um chamar para CreateEvent.

Todos os nomeado objetos sincronização são armazenados na mesma fila. Para determinar se CreateEvent criado ou aberto um objeto, chamar o função GetLastError imediatamente após chamado CreateEvent.

Se GetLastError Retorna ERROR_ALREADY_EXISTS, a chamar aberto um evento. Em outras palavras, se o nome especificado em um chamar para CreateEvent corresponde ao nome de um objeto evento, a função retorna o identificador do objeto.

Quando você usa essa técnica para objetos evento, nenhum dos processos de chamado devem solicitação apropriar imediata do evento porque ele é tiver certeza sobre qual processo seria a propriedade get.

Para sinalizar um evento, use o SetEvent ou PulseEvent função. SetEvent Não redefinir automaticamente o objeto evento para um não sinalizado estado. PulseEvent sinaliza o evento e, em seguida, redefine o evento. Para eventos manuais, PulseEvent Desbloqueia todos os segmentos que estão aguardando para o evento. Para eventos automáticos, PulseEvent Desbloqueia somente um segmento.

Se um objeto evento pode redefinir propriamente dita, use SetEvent Para sinalizar a redefinir. O objeto evento fica então redefinir para o não sinalizado estado quando um segmento está desbloqueado após esperar para esse evento.

Para redefinir manualmente um evento, use a função ResetEvent.

Para fechar um objeto, chamar evento CloseHandle. Se o objeto evento é nomeado, Windows Embedded CE mantém um contagem de referência sobre o objeto, e você deve fazer um chamar para CloseHandle Para cada chamar para CreateEvent.

Um segmento único pode especificar objetos evento diferentes em várias simultâneas sobreposto operações. Se esse for a maiúsculas e minúsculas, use um múltiplo - objeto esperar função aguardar o estado de um objeto evento ser sinalizado.

Você também pode usar objetos evento em um número de situações para notificar um segmento em espera da ocorrência de um evento. De exemplo, dispositivos de comunicação usam um objeto evento para sinalizar a sua conclusão.

O seguinte exemplo de código mostra um aplicativo que usa objetos evento para evitar vários segmentos de ler de uma reserva memória compartilhada enquanto um mestre segmento está gravando para essa reserva.

O mestre segmento usa o CreateEvent função para criar um manual-redefinir evento objeto. O mestre segmento define o objeto evento para um não sinalizado estado quando ele está gravando para a reserva, e ele então redefine o objeto para um sinalizado estado Quando ele terminar de escrita.

O mestre segmento, em seguida, cria vários segmentos leitor e uma auto-redefinir evento objeto para cada segmento. Cada segmento leitor define seu objeto evento para um sinalizado estado a ele não é ler a partir de reserva.

// Use event objects to protect buffer:
VOID ReadThreadFunction (LPVOID lpParam);  // Forward declaration
#define NUMTHREADS 4
HANDLE  hGlobalWriteEvent;
HANDLE  hReadEvents[NUMTHREADS];
void CreateEventsAndThreads (void)
{
   HANDLE hThread;   // Newlycreated thread handle
   DWORD dwThreadID; // Newlycreated thread ID value
   int i;            // For-loop counter
   hGlobalWriteEvent = CreateEvent (NULL, // No security attributes
                                   TRUE, // Manual-reset event
                                   TRUE, // Initial state is signaled
                                   TEXT("WriteEvent"));
                                   // Object name
   if (hGlobalWriteEvent == NULL)
      {
         // Your code to deal with the error goes here.
      }
   for (i = 0; i < NUMTHREADS; i++)
   {
      hReadEvents[i] = CreateEvent (NULL, // No security attributes
                                   FALSE, // Auto-reset event
                                   TRUE, // Initial state is signaled
                                   NULL); // Object not named
         if (hReadEvents[i] == NULL)
         {
            // Your code to deal with the error goes here.
         }
      hThread = CreateThread (NULL, // No security attributes in Windows Embedded CE
                             0, // Must be 0 in Windows Embedded CE
                             (LPTHREAD_START_ROUTINE) ReadThreadFunction
                             &hReadEvents[i], // Pass new thread's event handle
                             0, // Thread runs immediately
                             &dwThreadID); // Returned ID value (ignored)
      if (hThread == NULL)
      {
         // Your code to deal with the error goes here.
      }
   }
}

No seguinte exemplo de código, antes de mestre segmento grava a reserva compartilhada, ele usa ResetEvent Para definir o estado de hGlobalWriteEvent, que é um variável global Application-defined, para um não sinalizado estado. Isso bloqueia os segmentos leitor de iniciar um operação de leitura.

O mestre segmento em seguida, usa a função WaitForSingleObject para esperar por todos os segmentos leitor para concluir atual ler operações. Quando a executar um loop de chamadas para WaitForSingleObject está completo, o mestre segmento segura pode gravar a reserva.

Depois que ele terminar escrita, o mestre conjuntos segmento hGlobalWriteEvent e todos os leitor-eventos segmento a um sinalizado estado, que permite que os segmentos leitor para continuar seu ler operações.

O exemplo não usa a função WaitForMultipleObjects porque em Windows Embedded CE o fWaitAll sinalizador deve ser definido como FALSE. Para obter mais informações sobre funções de espera, consulte Wait Functions.

// Use WaitForSingleObject to stop reads during write.
int WriteToBuffer (void)
   {
      DWORD dwWaitResult;
      int i;
      // Block all read threads from starting any new operations.
      if (!ResetEvent (hGlobalWriteEvent))
         {
            // Your code to deal with the error goes here.
         }
      // Wait for all the read events to be signaled (threads done).
      for (i = 0; i < NUMTHREADS; i++)
         {
            dwWaitResult = WaitForSingleObject (hReadEvents[i], INFINITE);
            if (WAIT_OBJECT_0 != dwWaitResult)
               {
                  // Your code to deal with the error goes here.
               }
         }
      // Now it is okay to write to the shared buffer, so that code goes here. Put all the events back to signaled (so read threads can run).
      for(i = 0; i < NUMTHREADS; i++)
         {
            if (!SetEvent (hReadEvents[i]))
               {
                  // Your code to deal with the error goes here.
               }
            }
         if (!SetEvent (hGlobalWriteEvent))
            {
               // Your code to deal with the error goes here.
            }
         return 1;
      }
   }
}

No seguinte exemplo de código, antes de iniciar um operação de leitura, cada segmento leitor utiliza o WaitForSingleObject função para aguardar o variável global Application-defined hGlobalWriteEvente em seguida, usa-lo novamente para esperar por sua própria ler evento ser sinalizado.

Quando a executar um loop de chamadas para WaitForSingleObject está completo, a leitor segmento automática-redefinir evento é redefinir para um não sinalizado estado. Isso bloqueia o mestre segmento de gravar a reserva até que o segmento leitor utiliza o SetEvent função para redefinir o estado evento para um sinalizado estado.

// Block master thread from writing to the buffer until ready:
VOID ReadThreadFunction (LPVOID lpParam)
{
   DWORD dwWaitResult;
   HANDLE hEvent;
   BOOL bStayInLoop;
   hEvent = * (HANDLE *) lpParam;   // This thread's read event
   bStayInLoop = TRUE;
   while (bStayInLoop)
   {
      // First, wait for the master thread's event.
      WaitForSingleObject (hGlobalWriteEvent, INFINITE);
      if (WAIT_OBJECT_0 != dwWaitResult)
         {
            // Your code to deal with the error goes here.
         }
      // Now, wait for this thread's event object.
      WaitForSingleObject (hEvent, INFINITE);
      if (WAIT_OBJECT_0 != dwWaitResult)
         {
            // Your code to deal with the error goes here.
         }
      // Now it is okay to read the shared buffer. The code to do that goes here. When it is time for the thread to quit, set the bStayInLoop variable to FALSE. Now, signal that this thread is done with the buffer.
      if (!SetEvent (hEvent))
         {
            // Your code to deal with the error goes here.
         }
      }
   }
}

O seguinte define exemplo de código WriteToBuffer:

static _inline int
WriteToBuffer(PBUFFER pBuffer, PVOID pvBuf, DWORD cbBuf)

O seguinte exemplo de código mostra como usar WriteToBuffer:

static _inline int
WriteALetter(PBUFFER pBuffer, P_LTR pLetter)
{
   return (WriteToBuffer(pBuffer, pLetter, sizeof(P_LTR)));
}

See Also

Concepts

Synchronization