2010-06-16 3 views
4

J'essaie d'améliorer la portabilité d'une application C++ en utilisant boost: threads à la place de notre propre wrapper sur les threads Win32, et le problème de terminaison de thread gracieux (encore une fois) fait sa tête laide. Sur win32 pur, j'interromps les threads en utilisant QueueUserAPC pour lancer une exception "thread_interrupt" qui provoque le nettoyage de tous les objets RAII en sortie as described here. Toute fonction OS 'alertable' peut être interrompue de cette façon, donc des choses comme les attentes mutex, sleep, serial et socket E/S sont tous des points d'interruption possibles.boost :: threads - comment faire un arrêt gracieux?

Cependant, boost: mutex etc. ne sont pas "alertable" par QueueUserAPC sur win32 - ils appellent des choses comme sommeil (n) plutôt que SleepEx (n, true))

fils de Boost ont une « interruption "mécanisme (qui implique de la même manière de lancer une exception) mais il semble avoir l'inconvénient que SEULMENT les appels boost :: thread sont interrompus, donc une bibliothèque de socket tierce (par exemple) ne peut pas être interrompue.

Que faire? Je pourrais modifier la source d'amplification localement pour la rendre interruptible, mais cela semble être un mauvais choix et je ne pense pas que cela facilite la portabilité. L'application entière REDESSINER pour supprimer l'exigence d'arrêt de fil gracieux est une route ... De la même façon peu attrayante

+0

Je me demandais, qu'est-ce que vous voulez dire par une fermeture gracieuse? Parce que les interruptions sont plus comme une sorte de fermeture très laide si vous me demandez. – KillianDS

+0

@KillianDS - Par fermeture gracieuse, je veux dire que les objets sont détruits correctement à la sortie. Le boost 'interruption' lance une exception pour y parvenir. Un arrêt non-conforme ne détruit pas les objets, ce qui entraînera une fuite de ressources. – Roddy

+0

L'interruption gracieuse de bibliothèques tierces qui ne fournissent pas d'interface pour cela est impossible. – Basilevs

Répondre

1

J'ai une idée pour une solution partielle pour Win32, mais je dois encore tester:

Mon « fil interrompre "méthode pourrait appeler à la fois boost::thread.interrupt(), ET QueueUserAPC et la fonction appelée par QueueUserAPC appellerait simplement boost::interruption_point() pour permettre à l'interruption d'amplification de prendre le contrôle. Cela devrait signifier que le thread est interrompu (mais "différemment") à la fois lorsqu'il attend un objet de synchronisation boost ou un fichier windows natif "alertable".

Questions connexes