pthread avec une structure unique en paramètre C

J’ai ce code qui me cause des problèmes. Je sais que tous les threads lisent la même structure. Mais je ne sais pas comment résoudre ce problème.

#include  #include  #include  typedef struct { int a,b; } s_param; void * threadfunc(void *parm) { s_param *param2 = parm; printf("ID:%d and v:%d\n",param2->a,param2->b); pthread_exit(NULL); } int main(int argc, char **argv) { pthread_t thread[3]; int rc=0,i; void * status; for(i=0; i<3 ; ++i){ s_param param; param.b=10; param.a=i; rc = pthread_create(&thread[i], NULL, threadfunc, &param ); // !!!! if(rc){ exit(1); } } for(i=0; i<3 ; ++i){ pthread_join(thread[i],&status); } return 0; } 

sortie:

 ID:2 and v:10 ID:2 and v:10 ID:2 and v:10 

et ce dont j’ai besoin:

 ID:0 and v:10 ID:1 and v:10 ID:2 and v:10 

La scope du sparam dans la boucle for est statique dans cette boucle. Lorsque vous définissez .a et .b, vous écrivez encore et encore dans la même structure et les trois threads obtiennent un pointeur sur cette même structure.

Au lieu de cela, vous pouvez créer trois instances distinctes de la structure en faisant un tableau de celles-ci, comme suit:

 int main(int argc, char **argv) { pthread_t thread[3]; s_param param[3]; int rc=0,i; void * status; for(i=0; i<3 ; ++i){ param[i].b=10; param[i].a=i; rc = pthread_create(&thread[i], NULL, threadfunc, &param[i] ); // !!!! if(rc){ exit(1); } } ... etc 

Il convient de mentionner que la création des structures (et des threads) dans un tableau comme celui-ci n'est possible que dans la mesure où vous faites clairement une join () avec le thread principal. Si vous ne le faisiez pas, il serait conseillé d’allouer statiquement les structures en dehors de la fonction principale ou de les malloc du tas, car dès que le thread d’entrée quitte la fonction principale, le cadre de stack contenant le tableau deviendra invalide et sera bientôt écrasé de manière imprévisible.

param vit à la même place dans la stack pendant l’exécution de votre fonction main . Chaque fois que vous définissez de nouvelles valeurs, elles threadfunc les anciennes valeurs et tous les threadfunc regardent au même endroit en mémoire. malloc les structures, ou autrement créez-les à partir de différents emplacements de mémoire. (En outre, l’utilisation de la mémoire de stack pour les structures de données inter-thread est inquiétante; dès que la fonction que vous configurez dans les exits, la mémoire est invalide.)

param est une variable locale. Cela sort du cadre à la fin des accolades de la boucle. Vous devez s_param un nouveau s_param avec chaque thread.

Ou mieux, définissez une structure contenant à la fois pthread_t et s_param et utilisez ce type pour thread[3] .

 typedef struct { int a,b; pthread_t t; } s_param; int main(int argc, char **argv) { s_param thread[3]; // declare threads + params together int rc=0,i; void * status; for(i=0; i<3 ; ++i){ s_param *param = &thread[i]; // no persistent data declared here param->b=10; param->a=i; rc = pthread_create(&thread[i].t, NULL, threadfunc, &thread[i] ); // !!!! if(rc){ exit(1); } } …