Quelle est la manière la plus propre de créer un délai d’attente pour une boucle de temps?

API Windows / C / C ++

1. .... 2. .... 3. .... 4. while (flag1 != flag2) 5. { 6. SleepEx(100,FALSE); //waiting for flags to be equal (flags are set from another thread). 7. } 8. ..... 9. ..... 

Si les drapeaux ne sont pas égaux au bout de 7 secondes, je voudrais continuer sur la ligne 8.

Toute aide est appréciée. Merci.

Si vous attendez qu’un indicateur particulier soit défini ou qu’une heure soit atteinte, une solution beaucoup plus propre peut consister à utiliser un événement de réinitialisation automatique / manuel. Celles-ci sont conçues pour signaler les conditions entre les threads et ont des API très riches conçues sur elles. Par exemple, vous pouvez utiliser l’API WaitForMultipleObjects qui prend une valeur de délai explicite.

Ne pas interroger pour que les indicateurs changent. Même avec un sumil ou un rendement au cours de la boucle, cela ne fait que perdre des cycles de CPU.

Au lieu de cela, obtenez le thread qui définit les indicateurs pour vous signaler qu’ils ont été modifiés, probablement à l’aide d’un événement . Votre attente sur l’événement prend un délai, que vous pouvez modifier pour permettre une attente de 7 secondes au total.

Par exemple:

 Thread1: flag1 = foo; SetEvent(hEvent); Thread2: DWORD timeOutTotal = 7000; // 7 second timeout to start. while (flag1 != flag2 && timeOutTotal > 0) { // Wait for flags to change DWORD start = GetTickCount(); WaitForSingleObject(hEvent, timeOutTotal); DWORD end = GetTickCount(); // Don't let timeOutTotal accidently dip below 0. if ((end - start) > timeOutTotal) { timeOutTotal = 0; } else { timeOutTotal -= (end - start); } } 

Vous n’avez pas mentionné ce qui se passera si les drapeaux sont égaux.

En outre, si vous les testez sans aucune barrière de mémoire, vous ne pouvez pas garantir la présence d’écritures de la part de l’autre thread.

Votre meilleur pari est d’utiliser un événement et d’utiliser la fonction WaitForSingleObject avec un délai d’attente de 7000 millisecondes.

Vous pouvez utiliser QueryPerformanceCounter de WinAPI. Vérifiez-le avant le démarrage et demandez si le délai est écoulé. Cependant, il s’agit d’une timer haute résolution. Pour une résolution inférieure, utilisez GetTickCount (millisecondes).

Tout dépend si vous attendez activement (en faisant quelque chose) ou si vous attendez passivement un processus externe. Si c’est le cas, alors le code suivant utilisant Sleep sera beaucoup plus facile:

 int count = 0; while ( flag1 != flag2 && count < 700 ) { Sleep( 10 ); // wait 10ms ++count; } 

Si vous n'utilisez pas Sleep (ou Yield) et que votre application vérifie constamment une condition, vous allez gonfler le processeur sur lequel l'application s'exécute.

Si vous utilisez beaucoup WinAPI, vous devriez essayer une solution plus native, en savoir plus sur les fonctions de synchronisation de WinAPI.

Assurez-vous que vous faites un sleep() ou yield() là-dedans ou que vous mangerez tout le CPU (ou le core) en attente.

Je dirais “vérifier l’heure et si rien ne s’est passé sept secondes plus tard, alors briser la boucle.

Si votre application fait des choses en réseau, jetez un coup d’œil à l’appel POSIX select (), en particulier à la fonctionnalité timeout!