Comment arrêter un thread Pthread en cours d’exécution?

Comment puis-je quitter ou arrêter un fil immédiatement?

Comment puis-je le faire arrêter immédiatement lorsque l’utilisateur entre une réponse? Je veux qu’il se réinitialise pour chaque question.

Voici mon code où le threading est impliqué

int q1() { int timer_start; char ans[] = "lol"; char user_ans[50]; timer_start = pthread_create( &xtimer,NULL,(void*)timer_func,(void*)NULL); printf("What is the capital city of Peru?\n"); while(limit){ scanf("%s",user_ans); if(limit) { if(!strcmp(user_ans, ans)) { // printf("YAY!\n"); score++; // q2(); } else { game_over(); } } } } 

Sur la base de votre code, je peux vous donner une réponse simple:

Dans ce cas, n’utilisez pas de fil du tout.

Vous n’avez pas besoin d’eux. Stocker l’heure de début, laisser l’utilisateur répondre, vérifier l’heure à nouveau une fois que l’utilisateur a donné une réponse.

 { time_t startTimeSec = time(NULL); // answering time_t endTimeSec = time(NULL); time_t timeTakenSec = endTime-startTime; if (timeTaken > 10) { // do your thing } } 

Pour répondre à ta question:

Vous devez utiliser une variable volatile ou protégée par mutex pour communiquer de manière asynchrone entre les threads. Définissez cette variable à partir d’un thread et vérifiez-la dans un autre. Puis réinitialisez sa valeur et répétez. Un simple extrait:

 int stopIssued = 0; pthread_mutex_t stopMutex; int getStopIssued(void) { int ret = 0; pthread_mutex_lock(&stopMutex); ret = stopIssued; pthread_mutex_unlock(&stopMutex); return ret; } void setStopIssued(int val) { pthread_mutex_lock(&stopMutex); stopIssued = val; pthread_mutex_unlock(&stopMutex); } 

Utiliser pthread_cancel() est une option, mais je ne conseillerais pas de le faire. Vous devrez vérifier l’état des threads après le retour de cet appel, car pthread_cancel() n’attend pas l’arrêt réel du thread. Et, ce qui est encore plus important pour moi, j’envisage de l’utiliser mal.

Vous pouvez simplement appeler pthread_cancel sur ce thread pour le quitter. Et vous pouvez envoyer le signal SIGSTOP / SIGCONT via pthread_kill pour l’arrêter / le redémarrer.


Mais si tout ce que vous voulez, c’est une timer, pourquoi devez-vous enfiler?

Utiliser des méthodes pour arrêter un thread est une méthode brutale. Vous devriez plutôt demander poliment au fil de s’arrêter en signalant. Ainsi, le thread aura une option à ranger après lui-même, par exemple s’il a alloué de la mémoire, ce qu’il n’aura aucune occasion de faire si le thread est annulé.

Le procédé est relativement simple et ne comprend aucune signalisation de système d’exploitation:

définir une variable d’état ou une structure de thread en dehors du thread. Pointez-le sur pthread_create et déréférencez la variable d’état dans le thread.

 int thread_state = 0; // 0: normal, -1: stop thread, 1: do something static void *thread_1 (void *arg) { int* pthread_state = arg; ... // initialize the thread locals while(1) { switch( *pthread_state ) { case 0: // normal thread loop ... break; case -1: ... // tidy or whatever is necessary pthread_exit(0); // exit the thread signalling normal return break; case 1: // ... // do something special break; } } } pthread_create (&t_1, NULL, thread_1, (void*)&thread_state); ... thread_state = -1; // signal to the thread to stop // maybe use pthread_exit(0) to exit main. // this will leave the threads running until they have finished tidy etc. 

Il est même possible de communiquer avec le fil en utilisant une structure à condition qu’il s’agisse de simples variables “atomiques” ou qu’un simple mécanisme de prise de contact soit établi. Sinon, il peut être nécessaire d’utiliser mutex. Utilisez pthread_join pour attendre la fin des threads.

La suggestion de @ Naruil d’appeler pthread_cancel () est à peu près la meilleure solution que j’ai trouvée, mais cela ne fonctionnera pas si vous n’avez pas fait les choses suivantes.

Selon la page de manuel de pthread_cancel, pthread_cancelibility dépend de deux choses

  1. état_cancel_état.
  2. thread_cancel_type.

thread_cancel_state est PTHREAD_CANCEL_ENABLE par défaut. Par conséquent, notre principale préoccupation concerne le type thread_cancel_type ; sa valeur par défaut est le type PTHREAD_CANCEL_DEFFERED, mais nous devons annuler cette action.

Suivant un exemple donné ::

 #include  #include  void *thread_runner(void* arg) { //catch the pthread_object as argument pthread_t obj = *((pthread_t*)arg); //ENABLING THE CANCEL FUNCTIONALITY int prevType; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &prevType); int i=0; for( ; i < 11 ; i++)//1 - > 10 { if(i == 5) pthread_cancel(obj); else printf("count -- %d", i); } printf("done"); } int main(int argc, char *argv[]) { pthread_t obj; pthread_create(&obj, NULL, thread_runner, (void*)&obj); pthread_join(obj, NULL); return 0; } 

lancez-le en utilisant gcc filename.c -lpthread et affichez le texte suivant: count – 0 count – 1 count – 2 count – 3 count – 4

notez que le done n’est jamais imprimé car le fil a été annulé lorsque i est devenu 5 et le fil en cours a été annulé. Un merci spécial à @Naruil pour la suggestion “pthread_cancel”.