С man pthread_join :
int pthread_join(pthread_t thread, void **retval);
If retval is not NULL, then pthread_join() copies the exit status of
the target thread (i.e., the value that the target thread supplied to
pthread_exit(3)) into the location pointed to by retval
Вы возвращаете play
значение переменной из каждого game()
, но сохраняете его в той же переменной, просто сохраняете его в массив.
int main() {
system("cls");
int PLAYERS;
printf("Players: \n");
scanf("%d", &PLAYERS);
printf("\n");
int i, j;
// using VLA from C99 isn't that much reliable, so i decided to use malloc here
// pthread_t id[PLAYERS];
pthread_t *id = malloc(sizeof(*id)*PLAYERS);
// int num_id[PLAYERS];
int *num_id = malloc(sizeof(*num_id)*PLAYERS);
// void *play[PLAYERS];
int *play = malloc(sizeof(*play)*PLAYERS);
// maybe think of a structure here?
// struct player { pthread_t *id; int num_id; int play; } *players = malloc(sizeof(*players)*PLAYERS);
pthread_barrier_init(&barrier, NULL, PLAYERS + 1);
for (i=0; i < PLAYERS; i++) {
num_id[i] = i;
pthread_create(&id[i], NULL, game, &num_id[i]);
}
pthread_barrier_wait(&barrier);
for (i=0; i < PLAYERS; i++) {
pthread_join(id[i], (void*)&play[i]);
}
pthread_barrier_destroy(&barrier);
for (i=0; i < PLAYERS; i++) {
printf("The hand of %d was %d\n", i, play[i]);
}
// you want to compare first hand with second one?
if (play[0] == play[1]) {
printf("First two hands were the same.\n");
}
free(id);
free(num_id);
free(play);
return 0;
}
Но я думаю, что лучшим способом было бы передать указатель на некоторую определенную структуру в качестве аргумента для потоков, например:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct player_s {
pthread_t *id;
int num_id;
int play;
};
pthread_barrier_t barrier;
void* game(void *arg0) {
struct player_s *p = arg0;
assert(p != NULL);
int player = p->num_id;
int random = player; // this is not random ;)
int play = random % 3;
if (play == 0) {
printf("Player %d: played Rock \n", player);
}
if (play == 1) {
printf("Player %d: played Paper \n", player);
}
if (play == 2) {
printf("Player %d: played Scissors \n", player);
}
pthread_barrier_wait(&barrier);
p->play = play; // save play variable
return NULL;
}
int main() {
system("cls");
int PLAYERS;
printf("Players: \n");
scanf("%d", &PLAYERS);
printf("\n");
int i, j;
struct player_s *players = malloc(sizeof(*players)*PLAYERS);
assert(players != NULL);
pthread_barrier_init(&barrier, NULL, PLAYERS + 1);
for (i=0; i < PLAYERS; i++) {
players[i].num_id = i;
pthread_create(&players[i].id, NULL, game, &players[i]);
}
pthread_barrier_wait(&barrier);
for (i=0; i < PLAYERS; i++) {
pthread_join(players[i].id, NULL);
}
pthread_barrier_destroy(&barrier);
for (i=0; i < PLAYERS; i++) {
printf("The hand of %d was %d\n", i, players[i].play);
}
// you want to compare first hand with second one?
if (players[0].play == players[1].play) {
printf("First two hands were the same.\n");
}
// compare first hand with all the others regardless of the array size
for(i = 0; i < PLAYERS; ++i) {
printf("The first hand was %d and the %d hand played %d, so they ", players[0].play, i, players[i].play);
if (players[0].play != players[i].play) {
printf("differ!\n");
} else {
printf("are the same!\n");
}
}
free(players);
return 0;
}