33 votes

Quelle est la meilleure façon de sortir d'un programme Haskell?

J'ai un programme qui utilise plusieurs threads. Si je comprends bien, lorsque le thread 0 sorties, tout le programme des sorties, indépendamment de toutes les autres threads qui pourraient encore être en cours d'exécution.

La chose est, ces autres threads peuvent avoir des fichiers ouverts. Naturellement, cela est enveloppé dans de la gestion des exceptions code proprement ferme les fichiers en cas de problème. Cela signifie aussi que si j'utilise killThread (ce qui est mis en œuvre par throwTo), le fichier doit également être fermée avant que le thread s'arrête.

Ma question est, si je viens de laisser thread 0 sortie, sans tenter d'arrêter les autres threads, tous les différents descripteurs de fichiers sera fermé bien? N'importe quel tampon de sortie se rincé?

En bref, je peux juste à la sortie, ou dois-je le supprimer manuellement les threads en premier?

4voto

user2407038 Points 4636

Vous pouvez utiliser Control.Concurrent.MVar pour atteindre cet objectif. Un MVar est essentiellement un drapeau qui est soit "vide" ou "full". Un thread peut essayer de lire un MVar et si elle est vide, il bloque le thread. Partout où vous avez un thread qui exécute des e / s de fichier, de créer un MVar , et le passer qu' MVar comme argument. Mettre tous les MVars vous créez en une liste:

main = do
  let mvars = sequence (replicate num_of_child_threads newEmptyMVar)
  returnVals <- sequence (zipWith (\m f -> f m) 
                                  mvars 
                                  (list_of_child_threads :: [MVar -> IO a])) 

Une fois qu'un enfant thread a fini de toutes les opérations sur les fichiers que vous êtes inquiet à ce sujet, écrivez à l' MVar. Au lieu d'écrire killThread que vous pouvez faire

mapM_ takeMVar mvars >> killThread 

et où votre thread de sortie sinon, il suffit de prendre tout l' MVars.

Voir la documentation sur le GHC simultanéité pour plus de détails.

3voto

MathematicalOrchid Points 15354

De mes tests, j'ai découvert quelques petites choses:

  1. exitFailure et les amis seulement travaillent dans le thread 0. (La documentation dit donc, si vous allez pour la peine de le lire. Ces fonctions renvoient des exceptions, qui sont ignorées silencieusement dans d'autres threads.)

  2. Si une exception tue ton thread, ou de tout le programme, toutes les poignées sont pas vidées. C'est atrocement gênant lorsque vous êtes désespérément à essayer de comprendre exactement où votre programme s'est planté!

Il semble donc qu'il si vous voulez vos trucs rincé avant les sorties de programme, puis vous avez à mettre en œuvre. Laisser thread 0 die ne permet pas d'évacuer des choses, ne pas jeter d'exception, tout en silence met fin à toutes les discussions sans courir les gestionnaires d'exception.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X