Fonctions d’attente
fonctions Wait autoriser un thread à bloquer son propre exécution. Les fonctions d’attente ne retournent pas tant que les critères spécifiés n’ont pas été remplis. Le type de fonction d’attente détermine l’ensemble de critères utilisés. Lorsqu’une fonction d’attente est appelée, elle vérifie si les critères d’attente ont été remplis. Si les critères n’ont pas été remplis, le thread appelant entre dans l’état d’attente jusqu’à ce que les conditions des critères d’attente aient été remplies ou que l’intervalle de délai d’attente spécifié s’écoule.
- fonctions d’attente à objet unique
- fonctions d’attente à plusieurs objets
- fonctions d’attente alertables
- fonctions d’attente inscrites
- en attente d’une adresse
- fonctions d’attente et intervalles de délai d’attente
- Fonctions d’attente et objets de synchronisation
- fonctions d’attente et création de Windows
Fonctions Wait à objet unique
LesSignalObjectAndWait, WaitForSingleObjectet fonctions WaitForSingleObjectEx nécessitent un handle à un objet de synchronisation. Ces fonctions retournent quand l’une des opérations suivantes se produit :
- L’objet spécifié est dans l’état signalé.
- L’intervalle de délai d’attente s’écoule. L’intervalle de délai d’attente peut être défini sur infinite pour spécifier que l’attente n’expire pas.
La fonction SignalObjectAndWait permet au thread appelant de définir atomiquement l’état d’un objet à signaler et d’attendre que l’état d’un autre objet soit défini sur signalé.
Fonctions d’attente à plusieurs objets
Les WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectset fonctions MsgWaitForMultipleObjectsEx permettent au thread appelant de spécifier un tableau contenant un ou plusieurs handles d’objets de synchronisation. Ces fonctions retournent quand l’une des opérations suivantes se produit :
- L’état d’un des objets spécifiés est défini sur signalé ou les états de tous les objets ont été définis sur signalés. Vous contrôlez si un ou tous les états seront utilisés dans l’appel de fonction.
- L’intervalle de délai d’attente s’écoule. L’intervalle de délai d’attente peut être défini sur infinite pour spécifier que l’attente n’expire pas.
La fonction MsgWaitForMultipleObjects et MsgWaitForMultipleObjectsEx vous permettent de spécifier des objets d’événement d’entrée dans le tableau de handles d’objets. Cette opération est effectuée lorsque vous spécifiez le type d’entrée à attendre dans la file d’attente d’entrée du thread. Par exemple, un thread peut utiliser MsgWaitForMultipleObjects pour bloquer son exécution jusqu’à ce que l’état d’un objet spécifié ait été défini sur signalé et qu’il existe une entrée de souris disponible dans la file d’attente d’entrée du thread. Le thread peut utiliser la fonction GetMessage ou PeekMessageA ou fonction PeekMessageW pour récupérer l’entrée.
Lorsque vous attendez que les états de tous les objets soient définis comme signalés, ces fonctions à plusieurs objets ne modifient pas les états des objets spécifiés tant que les états de tous les objets n’ont pas été signalés. Par exemple, l’état d’un objet mutex peut être signalé, mais le thread appelant n’obtient pas la propriété tant que les états des autres objets spécifiés dans le tableau ont également été définis pour signaler. En attendant, un autre thread peut obtenir la propriété de l’objet mutex, ce qui définit son état sur non signé.
Lorsque vous attendez que l’état d’un objet unique soit défini sur signalé, ces fonctions à plusieurs objets vérifient les handles du tableau dans l’ordre commençant par l’index 0, jusqu’à ce qu’un des objets soit signalé. Si plusieurs objets deviennent signalés, la fonction retourne l’index du premier handle dans le tableau dont l’objet a été signalé.
Fonctions d’attente pouvant être alertables
Les MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsExet fonctions WaitForSingleObjectEx diffèrent des autres fonctions d’attente dans lesquelles elles peuvent éventuellement effectuer une opération d’attente . Dans une opération d’attente alertable, la fonction peut retourner lorsque les conditions spécifiées sont remplies, mais elle peut également retourner si le système met en file d’attente une routine d’achèvement d’E/S ou un APC pour l’exécution par le thread en attente. Pour plus d’informations sur les opérations d’attente alertables et les routines d’achèvement des E/S, consultez synchronisation etd’entrée et de sortie superposées. Pour plus d’informations sur les API, consultez appels de procédure asynchrone.
Fonctions d’attente inscrites
La fonction RegisterWaitForSingleObject diffère des autres fonctions d’attente dans laquelle l’opération d’attente est effectuée par un thread du pool de threads . Lorsque les conditions spécifiées sont remplies, la fonction de rappel est exécutée par un thread de travail à partir du pool de threads.
Par défaut, une opération d’attente inscrite est une opération d’attente multiple. Le système réinitialise le minuteur chaque fois que l’événement est signalé (ou l’intervalle de délai d’attente s’écoule) jusqu’à ce que vous appeliez la fonction UnregisterWaitEx pour annuler l’opération. Pour spécifier qu’une opération d’attente ne doit être exécutée qu’une seule fois, définissez le paramètre dwFlags de RegisterWaitForSingleObject sur WT_EXECUTEONLYONCE.
Si le thread appelle des fonctions qui utilisent des API, définissez le paramètre dwFlags de RegisterWaitForSingleObject sur WT_EXECUTEINPERSISTENTTHREAD.
En attente d’une adresse
Un thread peut utiliser la fonction WaitOnAddress pour attendre que la valeur d’une adresse cible passe d’une valeur non souhaitée à n’importe quelle autre valeur. Cela permet aux threads d’attendre qu’une valeur change sans avoir à tourner ou à gérer les problèmes de synchronisation qui peuvent survenir lorsque le thread capture une valeur non souhaitée, mais que la valeur change avant que le thread puisse attendre.
WaitOnAddress retourne lorsque le code qui modifie la valeur cible signale la modification en appelant WakeByAddressSingle pour réveiller un seul thread d’attente ou WakeByAddressAll pour réveiller tous les threads en attente. Si un intervalle de délai d’attente est spécifié avec WaitOnAddress et qu’aucun thread n’appelle une fonction de veille, la fonction retourne lorsque l’intervalle de délai d’attente s’écoule. Si aucun intervalle de délai d’attente n’est spécifié, le thread attend indéfiniment.
Fonctions d’attente et intervalles de délai d’attente
La précision de l’intervalle de délai d’attente spécifié dépend de la résolution de l’horloge système. L’horloge système « ticks » à un rythme constant. Si l’intervalle de délai d’attente est inférieur à la résolution de l’horloge système, l’attente peut expirer en moins de la durée spécifiée. Si l’intervalle de délai d’attente est supérieur à une graduation mais inférieur à deux, l’attente peut être n’importe où entre une et deux cycles, et ainsi de suite.
Pour augmenter la précision de l’intervalle de délai d’attente pour les fonctions d’attente, appelez la fonction timeGetDevCaps pour déterminer la résolution minimale du minuteur prise en charge et la fonction timeBeginPeriod pour définir la résolution du minuteur sur son minimum. Soyez prudent lorsque vous appelez timeBeginPeriod, car les appels fréquents peuvent affecter considérablement l’horloge système, l’utilisation de l’alimentation du système et le planificateur. Si vous appelez timeBeginPeriod, appelez-le une fois tôt dans l’application et veillez à appeler la fonction timeEndPeriod à la fin de l’application.
Fonctions d’attente et objets de synchronisation
Les fonctions d’attente peuvent modifier les états de certains types d’objets de synchronisation . La modification se produit uniquement pour l’objet ou les objets dont l’état signalé a provoqué le retour de la fonction. Les fonctions d’attente peuvent modifier les états des objets de synchronisation comme suit :
- Le nombre d’un objet sémaphore diminue d’un, et l’état du sémaphore est défini sur non signé si son nombre est égal à zéro.
- Les états de mutex, d’événement de réinitialisation automatique et d’objets de notification de modification sont définis sur non signés.
- L’état d’un minuteur de synchronisation est défini sur non signé.
- Les états de l’événement de réinitialisation manuelle, du minuteur de réinitialisation manuelle, du processus, du thread et des objets d’entrée de console ne sont pas affectés par une fonction d’attente.
Fonctions d’attente et création de Windows
Vous devez être prudent lors de l’utilisation des fonctions d’attente et du code qui créent directement ou indirectement des fenêtres. Si un thread crée des fenêtres, il doit traiter les messages. Les diffusions de messages sont envoyées à toutes les fenêtres du système. Si vous avez un thread qui utilise une fonction d’attente sans intervalle de délai d’attente, le système interblocage. Deux exemples de code qui créent indirectement des fenêtres sont DDE et la fonction CoInitialize. Par conséquent, si vous avez un thread qui crée des fenêtres, utilisez MsgWaitForMultipleObjects ou MsgWaitForMultipleObjectsEx, plutôt que les autres fonctions d’attente.