Comment retourner une valeur de thread dans C

Je suis nouveau sur C et j’aimerais jouer un peu avec les discussions. Je voudrais retourner une valeur d’un thread en utilisant pthread_exit()

Mon code est le suivant:

 #include  #include  void *myThread() { int ret = 42; pthread_exit(&ret); } int main() { pthread_t tid; void *status; pthread_create(&tid, NULL, myThread, NULL); pthread_join(tid, &status); printf("%d\n",*(int*)status); return 0; } 

Je m’attendrais à ce que la sortie du programme “42 \ n”, mais il sort un nombre aléatoire. Comment puis-je imprimer la valeur retournée?

EDIT: Selon les premières réponses, le problème est que je renvoie le pointeur à la variable locale. Quelle est la meilleure pratique pour retourner / stocker des variables de plusieurs threads? Une table de hachage globale?

Merci d’avance

Vous retournez l’adresse d’une variable locale, qui n’existe plus lorsque la fonction thread se ferme. Dans tous les cas, pourquoi appeler pthread_exit? pourquoi ne pas simplement renvoyer une valeur de la fonction thread?

 void *myThread() { return (void *) 42; } 

et puis en main:

 printf("%d\n",(int)status); 

Si vous avez besoin de renvoyer une valeur compliquée telle qu’une structure, il est probablement plus facile de l’allouer dynamicment via malloc () et de renvoyer un pointeur. Bien entendu, le code qui a initié le thread sera alors responsable de la libération de la mémoire.

Vous avez renvoyé un pointeur sur une variable locale. C’est mauvais même si les threads ne sont pas impliqués.

La façon habituelle de le faire, lorsque le thread qui démarre est le même thread que celui qui se joint, serait de passer un pointeur sur un int, dans un emplacement géré par l’appelant, en tant que 4ème paramètre de pthread_create. Cela devient alors le (seul) paramètre du point d’entrée du thread. Vous pouvez (si vous le souhaitez) utiliser la valeur de sortie du thread pour indiquer le succès:

 #include  #include  int something_worked(void) { /* thread operation might fail, so here's a silly example */ void *p = malloc(10); free(p); return p ? 1 : 0; } void *myThread(void *result) { if (something_worked()) { *((int*)result) = 42; pthread_exit(result); } else { pthread_exit(0); } } int main() { pthread_t tid; void *status = 0; int result; pthread_create(&tid, NULL, myThread, &result); pthread_join(tid, &status); if (status != 0) { printf("%d\n",result); } else { printf("thread failed\n"); } return 0; } 

Si vous devez absolument utiliser la valeur d’exit de thread pour une structure, vous devrez alors l’allouer dynamicment (et vous assurer que quiconque se joint au thread le libère). Ce n’est pas idéal, cependant.

Voici une solution correcte. Dans ce cas, tdata est alloué dans le thread principal et il y a un espace pour que le thread place son résultat.

 #include  #include  typedef struct thread_data { int a; int b; int result; } thread_data; void *myThread(void *arg) { thread_data *tdata=(thread_data *)arg; int a=tdata->a; int b=tdata->b; int result=a+b; tdata->result=result; pthread_exit(NULL); } int main() { pthread_t tid; thread_data tdata; tdata.a=10; tdata.b=32; pthread_create(&tid, NULL, myThread, (void *)&tdata); pthread_join(tid, NULL); printf("%d + %d = %d\n", tdata.a, tdata.b, tdata.result); return 0; } 

Je pense que vous devez stocker le nombre sur le tas. La variable int ret était sur la stack et a été détruite à la fin de l’exécution de la fonction myThread .

 void *myThread() { int *ret = malloc(sizeof(int)); if (ret == NULL) { // ... } *ret = 42; pthread_exit(ret); } 

N’oubliez pas de le free quand vous n’en avez pas besoin 🙂

Une autre solution consiste à renvoyer le nombre comme valeur du pointeur, comme le suggère Neil Butterworth.

Vous retournez une référence à ret qui est une variable sur la stack.

 #include #include void* myprint(void *x) { int k = *((int *)x); printf("\n Thread created.. value of k [%d]\n",k); //k =11; pthread_exit((void *)k); } int main() { pthread_t th1; int x =5; int *y; pthread_create(&th1,NULL,myprint,(void*)&x); pthread_join(th1,(void*)&y); printf("\n Exit value is [%d]\n",y); } 

Question: Quelle est la meilleure pratique pour retourner / stocker des variables de plusieurs threads? Une table de hachage globale?

Cela dépend totalement de ce que vous voulez retourner et comment vous l’utiliseriez? Si vous voulez renvoyer uniquement le statut du thread (dites si le thread a terminé ce qu’il a l’intention de faire), utilisez simplement pthread_exit ou utilisez une instruction return pour renvoyer la valeur de la fonction du thread.

Toutefois, si vous souhaitez plus d’informations qui seront utilisées pour un traitement ultérieur, vous pouvez utiliser la structure de données globale. Mais, dans ce cas, vous devez gérer les problèmes de concurrence en utilisant les primitives de synchronisation appropriées. Ou vous pouvez allouer de la mémoire dynamic (de préférence pour la structure dans laquelle vous voulez stocker les données) et l’envoyer via pthread_exit et une fois que le thread se joint, vous le mettez à jour dans une autre structure globale. De cette manière, seul le thread principal mettra à jour la structure globale et les problèmes de concurrence seront résolus. Mais, vous devez vous assurer de libérer toute la mémoire allouée par différents threads.

si vous n’êtes pas à l’aise avec le retour d’adresses et que vous n’avez qu’une seule variable, par exemple. une valeur entière à retourner, vous pouvez même la transtyper dans (void *) avant de la passer, puis la collecter dans (int) lorsque vous la collectez dans la main. Vous avez la valeur sans lancer des avertissements laids.