2012-07-03 3 views
0

Le (pseudo) code suivant induit un comportement que je ne comprends pas. J'ai 2 fils parallèles. Les deux font le même calcul (complexe) mais je ne sais pas lequel finira le premier. Exécuter à plusieurs reprises, il existe des cas où le premier est plus rapide et les cas où le second est plus rapide. C'est correct et fonctionne comme prévu. Ensuite, le premier thread réussi devrait terminer l'autre thread et les deux devraient se croiser. Cependant, si le premier solveur se termine, tout fonctionne mais si le second se termine en premier, la "commande de jointure" ne reconnaît pas que le premier solveur est terminé (donc la jointure attend éternellement, le programme ne continue pas). Des idées de ce que j'ai fait de mal ou de ce que je pourrais faire différemment?Annulation Pthread en C++

void* thread_function(...) 
{ 
    do_some_complex_task(); 
    if (successfull && first_finsihed) 
    { 
     pthread_chancel(other_thread); 
    } 
} 

int main() 
{ 
    std::vector<pthread_t*> store; 
    store.resize(2); 

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 

    pthread_create(store[0], NULL, thread_function, ...); 
    pthread_create(store[1], NULL, thread_function, ...); 

    pthread_join(*store[0], NULL); 
    pthread_join(*store[1], NULL); 
} 

PS. Si le pseudo code n'est pas assez détaillé, faites le moi savoir.

Répondre

1

Basé sur le pseudo code, un problème peut être que les threads ont une annulation différée (la valeur par défaut) au lieu de l'annulation asynchrone. Si le thread annulé n'atteint jamais cancellation point, alors pthread_join bloquerait. Lors de l'appel pthread_create, le thread nouvellement créé hérite du du thread appelant: Signal

Essayez d'appeler pthread_setcanceltype à partir des threads que vous souhaitez annuler. Vous pouvez également envisager d'attacher un débogueur au programme pour identifier l'état actuel des threads.

Idéalement, si cela est possible, envisager d'éviter pthread_cancel. Bien que les appels pthread soient documentés, il peut être difficile d'obtenir et de maintenir le comportement exact en raison de tous les détails mineurs. Il est généralement plus facile de définir un indicateur qui indique que le thread est défini pour quitter et commencer à revenir des fonctions lorsqu'il est défini. Dans do_some_complex_task, envisagez de fractionner la tâche complexe en tâches plus petites et vérifiez l'annulation entre chaque tâche plus petite.

1

N'utilisez pas pthread_cancel - utilisez un état global et vérifiez-le dans la "boucle principale" de chaque thread. Réglez-le "sur" juste avant la sortie de la fonction du fil.

+0

Et comment puis-je terminer mon autre thread alors? "do_some_complex_stask()" mon temps prend beaucoup de temps, donc je veux arrêter le fil non-fini dès que possible. – Martin

+0

si 'do_some_complex_task()' alloue de la mémoire, lorsque vous appelez "pthread_cancel()" à partir de l'autre thread, cette mémoire sera perdue. Donc, de toute façon, ce n'est pas la bonne façon. Vous devrez trouver un moyen d'abandonner 'do_some_complex_task()' à la demande. – elcuco