La mise en attente du thread est-elle optimale?

L’application a un fil auxiliaire. Ce thread n’est pas destiné à fonctionner tout le temps, mais le processus principal peut l’appeler très souvent.

Alors, ma question est la suivante: qu’est-ce qui est le plus optimal en termes de performances du processeur: suspendre le thread lorsqu’il n’est pas utilisé ou le garder en vie et utiliser la fonction WaitForSingleObject pour attendre un signal du processus principal?

En termes de ressources CPU utilisées, les deux solutions sont les mêmes – le thread qui est suspendu et thread qui attend dans WaitForSingleObject pour un object qui n’est pas signalé ne reçoivent aucun cycle du processeur.

Cela dit, WaitForSingleObject est presque toujours une solution préférée car le code qui l’utilise sera beaucoup plus “naturel” – plus facile à lire et plus facile à corriger. Suspendre / reprendre des threads peut être dangereux, car vous devez prendre beaucoup de soin pour vous assurer que vous suspendez un thread dans un état où sa suspension ne nuira pas (imaginez suspendre un thread qui contient actuellement un mutex).

Je suppose que Andrei n’utilise pas Delphi pour écrire .NET et que Suspend ne se traduit donc pas par System.Threading.Thread.Suspend mais par SuspendThread Win32 API.

Je le déconseillerais fortement. Si vous suspendez le thread à un moment arbitraire, vous ne savez pas ce qui va se passer (par exemple, vous pouvez suspendre le thread dans un tel état si une ressource partagée est bloquée). Si toutefois vous savez déjà que le thread est en état de suspension, utilisez simplement WaitForSingleObject (ou tout autre appel WaitFor) – il sera tout aussi efficace que de suspendre le thread, c.-à-d.

Que voulez-vous dire par “suspendre”? WaitForSingleObject suspendra le thread, c’est-à-dire qu’il ne consumra aucun processeur, jusqu’à ce que le signal arrive.

Si c’est un thread de travail qui a des unités de travail qui lui sont données en externe, il devrait certainement utiliser des objects de signalisation car cela garantira qu’il n’utilise pas inutilement le processeur.

Si elle a son propre travail à faire, c’est autre chose. Je ne voudrais pas suspendre le thread d’un autre thread (que se passe-t-il s’il y a deux threads qui lui fournissent du travail?) – ma règle de base est que les threads doivent contrôler leur propre durée de vie avec des suggestions d’autres threads. Cela localise tout le contrôle dans le thread lui-même.

Voir l’excellent tutoriel sur le multi-threading dans Delphi: Multi Threading Tutorial

Une autre option serait le TMonitor introduit dans Delphi 2009, qui a des fonctions comme Wait, Pulse et PulseAll pour garder les threads inactifs quand il n’y a rien à faire, et les notifier dès qu’ils doivent continuer leur travail. Il est modélisé librement après le locking de l’object en Java. Comme ici, les objects Delphi ont maintenant un champ “lock” qui peut être utilisé pour la synchronisation de threads.

Un blog qui donne un exemple de classe de files d’attente peut être trouvé à http://delphihaven.wordpress.com/2011/05/04/using-tmonitor-1/

Malheureusement, il y avait un bogue dans l’implémentation de TMonitor, qui semble être corrigé dans XE2.