2017-06-28 4 views
1

La première chose qu'on m'avait dite quand on avait commencé à travailler avec pthreads était - vous devriez éviter l'annulation de thread force, comme pthread_cancel. Au lieu de cela, nous devrions utiliser la notification d'annulation de thread via le canal de communication des threads.Les threads POSIX: la meilleure méthode d'interruption

Si nous avons une tâche vraiment longue à exécuter dans le thread, nous divisons cette tâche en petits morceaux et vérifions l'indicateur d'annulation après chaque traitement de bloc. Comme ceci:

loop { 
    process_chunk(); 
    if (check_cancel_flag()) 
     break; 
} 

Mais quelle est la meilleure approche pour la mise en œuvre de cette fonction check_cancel_flag()?

Avec toute mon expérience en c et linux, je me souviens que ces méthodes:

  1. (Si vous avez un seul thread de travail) Vous pouvez utiliser sig_atomic_t comme type pour le drapeau d'annulation. Vérifiez-le dans la fonction check_cancel_flag() et marquez-le comme vrai dans le gestionnaire de signal du thread. Ensuite, appelez pthread_kill à partir du thread principal.

  2. Utilisez n'importe quel type de POD pour le drapeau d'annulation et protégez-le avec un mutex. Dans ce cas, vous aurez trop souvent besoin d'un verrou d'appel.

  3. Utilisez le mutex comme indicateur d'annulation. Vérifiez-le avec l'appel pthread_mutex_trylock. Si le thread principal libère ce mutex, il est temps de l'arrêter pour le thread de travail. (Pour C11) Utilisez les fonctions intégrées gcc _atomic (ou une autre bibliothèque atomique ASM) pour définir et vérifier le drapeau d'annulation.

Je ne me souviens de rien d'autre.

La question: Comment choisir la bonne approche? Connaissez-vous un repère sur ce problème?

+1

Il y a un [Article Wiki] (https://en.wikipedia.org/wiki/Monitor_%28synchronization%29#Condition_variables) discutant de la question exacte. –

+0

Je pense que c'est un peu différent, juste pour la mise en œuvre comsumer/producteur. En effet, j'utilise les files d'attente et les conditions d'attente, mais comment interrompre une longue tâche? –

+0

BTW, C11 a simple une qualification «_Atomic» pour les types de données qui fait l'affaire. 'sig_atomic_t' n'est jamais approprié, ses seules garanties sont en ce qui concerne les gestionnaires de signaux, et là il ne garantit que l'indivisibilité, pas les autres propriétés de cohérence de mémoire que vous voudriez avoir. –

Répondre

2

Une alternative consiste à utiliser un verrou de lecteur-graveur (pthread_rwlock_t) pour protéger le drapeau, car vos threads de travail doivent le lire fréquemment mais il n'est écrit qu'une seule fois.

Tant que le segment traité entre les vérifications du drapeau n'est pas trop petit, le surdébit sera insignifiant.