Passage de paramètre à pthread
J'ai le code suivant:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 100
struct thread_param {
char *f1;
char *f2;
int x;
};
void *thread_function(void *arg){
printf("%d\n", ((struct thread_param*)arg)->x);
}
int main(int argc, char *argvs[]){
int i, thread_cr_res = 0, thread_join_res;
pthread_t *threads;
threads = malloc(100 * sizeof(*threads));
if(threads == NULL){
fprintf(stderr,"MALLOC THREADS ERROR");
return (-1);
}
for(i = 0; i < NUM_THREADS; i++){
struct thread_param *tp;
if((tp = malloc(sizeof(*tp))) == NULL){
fprintf(stderr,"MALLOC THREAD_PARAM ERROR");
return (-1);
}
tp->f1 = "f1";
tp->f2 = "f2";
tp->x = i;
thread_cr_res = pthread_create(&threads[i],
NULL,
thread_function,
(void*)tp);
if(thread_cr_res != 0){
fprintf(stderr,"THREAD CREATE ERROR");
return (-1);
}
}
return (0);
}
Ce que je veux, c'est de l'impression de tous les nombres de 0 à 99, à partir de fils. Aussi, je suis d'expérimenter une façon de passer d'une structure comme un fil de paramètre d'entrée.
Ce que je trouve curieux, c'est que tous les nombres sont affichés, par exemple:
./a.out | grep 9
9
19
29
39
49
Et parfois, certains nombres sont affichés deux fois:
...
75
74
89
77
78
79
91
91
Pouvez-vous svp m'expliquer pourquoi est-ce arrivé ?
Aucune erreur n'est affichée.
PLUS TARD EDIT:
J'ai réécrit le code de @Yasir suggéré, à l'aide d'un pthread_join
. Le nouveau code ressemble à ceci:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 100
struct thread_param {
char *f1;
char *f2;
int x;
};
void *thread_function(void *arg){
printf("%d\n", ((struct thread_param*)arg)->x);
}
int main(int argc, char *argvs[]){
int i, thread_cr_res = 0, thread_join_res;
pthread_t *threads;
threads = malloc(100 * sizeof(*threads));
if(threads == NULL){
fprintf(stderr,"MALLOC THREADS ERROR");
return (-1);
}
for(i = 0; i < NUM_THREADS; i++){
struct thread_param *tp;
if((tp = malloc(sizeof(*tp))) == NULL){
fprintf(stderr,"MALLOC THREAD_PARAM ERROR");
return (-1);
}
tp->f1 = "f1";
tp->f2 = "f2";
tp->x = i;
thread_cr_res = pthread_create(&threads[i],
NULL,
thread_function,
(void*)tp);
if(thread_cr_res != 0){
fprintf(stderr,"THREAD CREATE ERROR");
return (-1);
}
}
/* Later edit, joining the threads */
for (i = 0; i < NUM_THREADS; i++){
thread_join_res = pthread_join(threads[i], NULL);
if(thread_join_res != 0){
fprintf(stderr, "JOIN ERROR");
return (-1);
}
}
return (0);
}
Après:
./a.out | sort
0
1
10
11
12
13
14
15
16
17
18
19
2
20
21
22
23
24
25
26
27
28
29
3
30
31
32
33
34
35
36
37
38
39
4
40
41
42
43
44
45
46
47
48
49
5
50
51
52
53
54
55
56
57
58
59
6
60
61
62
63
64
65
66
67
68
69
7
70
71
72
73
74
75
76
77
78
79
8
80
81
82
83
84
85
86
87
88
89
9
90
91
92
93
94
95
96
97
98
99
Le code agit comme il le devrait. Encore je ne peux pas m'expliquer pourquoi la première version du code a été sortie des doublons.
Linux / Ubuntu 32
OriginalL'auteur Andrei Ciobanu | 2010-04-17
Vous devez vous connecter pour publier un commentaire.
Utilisation
int pthread_join(pthread_t thread, void **value_ptr)
à attendre pour les threads de résiliation afin d'obtenir tous les résultats avant de thread principal de sortie. Aussi en raison desizeof(*tp)
vous vous retrouvez avec la taille de pointeur vers cette structure qui est de 4 octets de long sur 32 bits. Cela pourrait éventuellement réécrire d'autres structures dans la mémoire.sizeof(thread_param)
aurait plus de sens pour moi.Aussi
tp->f1 = "f1";
se réfère à une chaîne constante. I. e. vous n'avez pas enregistrer une chaîne de caractères dans la structure mais plutôt utilisé le même tampon pour tous vosthread_param
structures. Ce serait dangereux si"f1"
est un pointeur vers la variable de la mémoire tampon.UPD: Oui, les commentaires soufflet sur la taille sont corrects.
Peut-être parce que de
sizeof(*tp)
? Je suppose quesizeof(thread_param)
aurait plus de sens, sinon nous nous retrouvons avec une taille de pointeur vers cette structure qui est de 4 octets de long sur 32 bits.sizeof(*tp) est la même que sizeof(thread_param) . De toute façon merci pour le joindre à la pointe.
Quel est le problème avec
sizeof(*tp)
?sizeof(*tp) signifie "la taille de la chose que tp est un pointeur vers"
OriginalL'auteur Yasir Arsanukaev
Ceci est probablement lié à la façon dont stdio travaille dans les threads : afin de ne pas corrompre la sortie (et plus généralement de tous les autres cours d'eau), stdio utiliser le verrouillage. Et si votre thread principal de sortie, de mauvaises choses peuvent se produire, comme la fermeture de volets, qui devra être rouvert /vidées par d'autres threads.
Noter que, puisqu'il y a de verrouillage autour de stdio de la fonction, il y a de contention et printf() l'appel est devenu une sorte de point de synchronisation qui va changer la façon dont vous le programme de travail.
OriginalL'auteur Yann Droneaud