Funções de espera
funções de espera permitir que um thread bloqueie sua própria execução. As funções de espera não retornam até que os critérios especificados tenham sido atendidos. O tipo de função de espera determina o conjunto de critérios utilizados. Quando uma função de espera é chamada, ela verifica se os critérios de espera foram atendidos. Se os critérios não tiverem sido atendidos, o thread de chamada entrará no estado de espera até que as condições dos critérios de espera tenham sido atendidas ou o intervalo de tempo limite especificado decorria.
- Funções de espera de objeto único
- Funções de espera de vários objetos
- funções de espera alertável
- Funções de espera registadas
- Aguardando em um endereço
- Funções de espera e intervalos de tempo limite
- Funções de espera e objetos de sincronização
- funções de espera e criação de do Windows
Funções de espera de objeto único
As funções SignalObjectAndWait, WaitForSingleObjecte WaitForSingleObjectEx exigem um identificador para um objeto de sincronização. Essas funções retornam quando ocorre uma das seguintes situações:
- O objeto especificado está no estado sinalizado.
- O intervalo de tempo limite decorre. O intervalo de tempo limite pode ser definido como INFINITE para especificar que a espera não expirará.
A funçãoSignalObjectAndWait permite que o thread de chamada defina atomicamente o estado de um objeto como sinalizado e aguarde que o estado de outro objeto seja definido como sinalizado.
Funções de espera de vários objetos
As funções WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectse MsgWaitForMultipleObjectsEx permitem que o thread de chamada especifique uma matriz contendo um ou mais identificadores de objeto de sincronização. Essas funções retornam quando ocorre uma das seguintes situações:
- O estado de qualquer um dos objetos especificados é definido como sinalizado ou os estados de todos os objetos foram definidos como sinalizados. Você controla se um ou todos os estados serão usados na chamada de função.
- O intervalo de tempo limite decorre. O intervalo de tempo limite pode ser definido como INFINITE para especificar que a espera não expirará.
O MsgWaitForMultipleObjects e função de MsgWaitForMultipleObjectsEx permitem especificar objetos de evento de entrada na matriz de identificador de objeto. Isso é feito quando você especifica o tipo de entrada a ser aguardado na fila de entrada do thread. Por exemplo, um thread pode usar MsgWaitForMultipleObjects para bloquear sua execução até que o estado de um objeto especificado tenha sido definido como sinalizado e haja entrada do mouse disponível na fila de entrada do thread. O thread pode usar o GetMessage ou PeekMessageA ou função PeekMessageW para recuperar a entrada.
Ao aguardar que os estados de todos os objetos sejam definidos como sinalizados, essas funções de vários objetos não modificam os estados dos objetos especificados até que os estados de todos os objetos tenham sido sinalizados. Por exemplo, o estado de um objeto mutex pode ser sinalizado, mas o thread de chamada não obtém propriedade até que os estados dos outros objetos especificados na matriz também tenham sido definidos como sinalizados. Enquanto isso, algum outro thread pode obter a propriedade do objeto mutex, definindo assim seu estado como não sinalizado.
Ao aguardar que o estado de um único objeto seja definido como sinalizado, essas funções de vários objetos verificam as alças na matriz em ordem começando com o índice 0, até que um dos objetos seja sinalizado. Se vários objetos forem sinalizados, a função retornará o índice do primeiro identificador na matriz cujo objeto foi sinalizado.
Funções de espera alertáveis
As funções deMsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsExe WaitForSingleObjectEx diferem das outras funções de espera porque podem, opcionalmente, executar uma operação de espera alertável. Em uma operação de espera alertável, a função pode retornar quando as condições especificadas forem atendidas, mas também pode retornar se o sistema enfileirar uma rotina de conclusão de E/S ou um APC para execução pelo thread de espera. Para obter mais informações sobre operações de espera alertáveis e rotinas de conclusão de E/S, consulte sincronização ede entrada e saída sobrepostas. Para obter mais informações sobre APCs, consulte chamadas de procedimento assíncrono.
Funções de espera registadas
A funçãoRegisterWaitForSingleObject difere das outras funções de espera porque a operação de espera é executada por um thread do pool de threads . Quando as condições especificadas são atendidas, a função de retorno de chamada é executada por um thread de trabalho do pool de threads.
Por padrão, uma operação de espera registrada é uma operação de espera múltipla. O sistema redefine o temporizador sempre que o evento é sinalizado (ou o intervalo de tempo limite decorre) até que você chame a função UnregisterWaitEx para cancelar a operação. Para especificar que uma operação de espera deve ser executada apenas uma vez, defina o parâmetro dwFlags de RegisterWaitForSingleObject como WT_EXECUTEONLYONCE.
Se o thread chamar funções que usam APCs, defina o dwFlags parâmetro de RegisterWaitForSingleObject como WT_EXECUTEINPERSISTENTTHREAD.
Aguardando em um endereço
Um thread pode usar a função WaitOnAddress para aguardar que o valor de um endereço de destino mude de algum valor indesejado para qualquer outro valor. Isso permite que os threads esperem que um valor seja alterado sem ter que girar ou lidar com os problemas de sincronização que podem surgir quando o thread captura um valor indesejado, mas o valor muda antes que o thread possa esperar.
WaitOnAddress retorna quando o código que modifica o valor de destino sinaliza a alteração chamando WakeByAddressSingle para despertar um único thread de espera ou WakeByAddressAll para despertar todos os threads em espera. Se um intervalo de tempo limite for especificado com WaitOnAddress e nenhum thread chamar uma função wake, a função retornará quando o intervalo de tempo limite terminar. Se nenhum intervalo de tempo limite for especificado, o thread aguardará indefinidamente.
Funções de espera e intervalos de tempo limite
A precisão do intervalo de tempo limite especificado depende da resolução do relógio do sistema. O relógio do sistema "ticks" a uma taxa constante. Se o intervalo de tempo limite for menor do que a resolução do relógio do sistema, o tempo limite de espera pode ser inferior ao período de tempo especificado. Se o intervalo de tempo limite for maior que um tick, mas menor que dois, a espera pode ser em qualquer lugar entre um e dois ticks, e assim por diante.
Para aumentar a precisão do intervalo de tempo limite para as funções de espera, chame a função timeGetDevCaps para determinar a resolução mínima de temporizador suportada e a função timeBeginPeriod para definir a resolução do temporizador para seu mínimo. Tenha cuidado ao chamar timeBeginPeriod, pois as chamadas frequentes podem afetar significativamente o relógio do sistema, o uso de energia do sistema e o agendador. Se você chamar timeBeginPeriod, chame-o uma vez no início do aplicativo e certifique-se de chamar a função timeEndPeriod no final do aplicativo.
Funções de espera e objetos de sincronização
As funções de espera podem modificar os estados de alguns tipos de objetos de sincronização . A modificação ocorre apenas para o objeto ou objetos cujo estado sinalizado fez com que a função retornasse. As funções de espera podem modificar os estados dos objetos de sincronização da seguinte maneira:
- A contagem de um objeto semáforo diminui em um, e o estado do semáforo é definido como não sinalizado se sua contagem for zero.
- Os estados de mutex, evento de redefinição automática e objetos de notificação de alteração são definidos como não sinalizados.
- O estado de um temporizador de sincronização é definido como não sinalizado.
- Os estados do evento de redefinição manual, temporizador de redefinição manual, processo, thread e objetos de entrada do console não são afetados por uma função de espera.
Funções de espera e criação de janelas
Você tem que ter cuidado ao usar as funções de espera e código que direta ou indiretamente cria janelas. Se um thread cria qualquer janela, ele deve processar mensagens. As transmissões de mensagens são enviadas para todas as janelas do sistema. Se você tiver um thread que usa uma função de espera sem intervalo de tempo limite, o sistema será bloqueado. Dois exemplos de código que cria janelas indiretamente são o DDE e a função CoInitialize. Portanto, se você tiver um thread que cria janelas, use MsgWaitForMultipleObjects ou MsgWaitForMultipleObjectsEx, em vez das outras funções de espera.