Bonjour,

Je reviens encore une fois vers vous pour vous demander de l'aide. Je bloque sur un sujet qui utilise les threads et je précise que c'est la première fois que je les utilise de façon concrète.

L'objectif est de simuler le fonctionnement d’un jeu dans lequel n threads utilisent chacun un dé pour tirer un nombre aléatoire.
Une fois les dés tirés, un des threads (pas toujours le même) joue le rôle d’arbitre pour désigner le vainqueur, c’est-à-dire celui qui a tiré le plus grand nombre. S’il y a égalité, l’arbitre indique aux joueurs ceux qui doivent à nouveau s’affronter, et tous les joueurs participent ou regardent le nouveau tirage, qu’un nouveau thread arbitrera.
Lorsqu’un vainqueur est enfin trouvé, le thread principal est averti. Dès lors, le thread principal peut lancer une nouvelle partie ou ordonner aux n threads de s’arrêter.
Il y a quelques contraintes comme pas de variables globales.

J'ai plusieurs questions. Mais tout d'abord, comme on ne peut passer qu'un seul argument dans la création d'un thread, j'ai pensé à passer par une structure mais je n'ai pas trouvé comment la réaliser pour envoyer l'id du thread correspondant. De même, j'ai tenté de créer un tableau de scores pour savoir quel thread a tiré quelle valeur et les comparer. Mais je bloque pour gérer les cas d'égalité et de même forcer les threads à refaire des tirages s'il y a égalité entre ces derniers. Je suis un peu perdue et je pense que d'autres erreurs ont du se glisser.

Je mets ce que j'ai commencé à faire. Merci d'avance

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
 
 
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
 
void raler (const char* const msg) 
{
	perror (msg);
	exit(1);
}
 
typedef struct {
    int nb_faces;
    int *ids;
    int *scores;
} t_info;
 
pthread_barrier_t barriere_tirage, barriere_decision;
 
 
void *arbitre(void *arg) 
{
    t_info *info = arg;
    int vainqueur;
    int max_score = 0;
 
    for (int j = 0; j < n; j++) 
    {
        if (info->scores[j] > max_score) 
        {
            max_score = info->scores[j];
            vainqueur = j;
        } else if (info->scores[j] == max_score)
        {
            // gèrer les cas d'égalité ???
        }
    }
 
    if (egalité)
        printf("arbitre %i egalité %", ids.., );
 
    if (vainqueur)
        printf("arbitre %i egalité %", ids.., vainqueur);
 
    // attente des joueurs pour un nouveau tirage
    pthread_barrier_wait(&barriere_decision); 
 
    pthread_exit(NULL);
}
 
 
void *joueur(void *arg) 
{
    t_info *info = arg;
 
    // initialisation de la graine pour rand_r
    //PROBLEME POUR ID THREAD
    unsigned int seed = info->ids; 
 
    // attente que tous les joueurs soient prêts à tirer
    pthread_barrier_wait(&barriere_tirage); 
 
    // tirage d'une face aléatoire du dé
    int face = rand_r(&seed) % info->nb_faces + 1; 
 
    scores[ids] = face;
 
    printf ("thread %i tire %i",info->ids, face);
 
    pthread_exit(NULL);
}
 
 
int main(int argc, char *argv[]) {
 
    if (argc != 5) 
    {
        fprintf(1, "Usage: %s faces delai n p\n", argv[0]);
        exit (1);
    }
 
    t_info info;
 
    info.nb_faces = atoi(argv[1]);
    int delai = atoi(argv[2]);
    int n = atoi(argv[3]);
    int p = atoi(argv[4]);
 
    // pour la génération de nombres pseudo-aléatoires
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    unsigned int seed = ts.tv_nsec ^ ts.tv_sec;
    unsigned int* seedp = &seed;
    srand_r(*seedp, &rand_state);
 
    // allocation du tableau des threads
    pthread_t *threads = malloc(n * sizeof(pthread_t));
    if (threads == NULL)
        raler ("Erreur malloc");
 
    // allocation du tableau des identifiants des joueurs
    info.ids = malloc(n * sizeof(int));
    if (info.ids == NULL)
        raler ("Erreur malloc");
 
    info.scores = malloc(n * sizeof(int));
    if (info.scores == NULL)
        raler ("Erreur malloc");
 
 
    for (int i = 0; i < n; i++) 
            info.ids[i] = i;
            info.scores[i] = 0;
 
    for (int partie = 0, partie < p; partie++)
    { 
        printf ("debut partie %i\n", p);
 
        // initialisation de la barrière pour le tirage et la décision
        pthread_barrier_init(&barriere_tirage, NULL, n); 
        pthread_barrier_init(&barriere_decision, NULL, n+1); 
 
        for (int i = 0; i < n-1; i++) 
        {
            // création des threads joueurs
            pthread_create(&threads[i], NULL, joueur, &info);
            if (errno > 0);
                raler ("pthread_create"); 
        }
 
        // création du thread arbitre (doit être différent)
        // à chaque fois dont PROBLEME
        pthread_create(&threads[n-1], NULL, arbitre, &info); 
        if (errno > 0);
            raler ("pthread_create");
 
        for (int i = 0; i < n; i++) 
        {
            pthread_join(threads[i], NULL); // attente de la fin des threads
            if (errno > 0);
                raler ("pthread_join");
        }
 
        // destructions des deux barrières
        pthread_barrier_destroy(&barriere_tirage); 
        pthread_barrier_destroy(&barriere_decision); 
 
        printf ("fin partie %i\n", p);
    }
 
    printf ("fin du jeu");
 
    free(info.ids); // libération du tableau des identifiants des joueurs
    free(threads); // libération du tableau des threads
 
    return 0;
}