0
Considering the following code, what is the best way to synchronize the threads that add the vectors with the threads that populate the vectors ? I have tried several ways, such as mutex and/or pthread_cond_init, but none of them worked or had a good result. This code is for a college job, who is interested and get more information from them, readme.MD is available on github: https://github.com/Gabrielxdf/Trabalho-de-SO
Follows the code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <locale.h>
#include <time.h>
//declaração das variáveis globais
float *x;
float *y;
float *z;
pthread_mutex_t *mutexes;
pthread_cond_t pode_somar = PTHREAD_COND_INITIALIZER; // sinalizado quando z puder somar o x e o y
typedef struct
{
float* vetor;
unsigned int posInicial;
unsigned int posFinal;
unsigned int contMutexThread;
}Thread_preenche;
typedef struct
{
float* x;
float* y;
float* z;
unsigned int posInicial;
unsigned int posFinal;
unsigned int contMutexThread;
}Thread_soma;
void *preencheVetores(void *argPtr){
Thread_preenche *thread_t = (Thread_preenche*)argPtr;
unsigned int inicio = thread_t->posInicial;
unsigned int final = thread_t->posFinal;
//pthread_mutex_lock(&mutexes[thread_t->contMutexThread]);
//pthread_cond_signal(&pode_somar);
//pthread_mutex_unlock(&mutexes[thread_t->contMutexThread]);
for(;inicio <= final; inicio++){
thread_t->vetor[inicio] = (float)rand()/(float)(RAND_MAX/1.0);
//printf("x[%u] e o valor é: %f \n", inicio, x[inicio]);
}
pthread_exit(0);
}
void *somaVetores(void* argPtr){
Thread_soma *thread_z = (Thread_soma*)argPtr;
unsigned int inicio = thread_z->posInicial;
unsigned int final = thread_z->posFinal;
//pthread_mutex_lock(&mutexes[thread_z->contMutexThread]);
//pthread_cond_wait(&pode_somar, &mutexes[thread_z->contMutexThread]);
//pthread_mutex_unlock(&mutexes[thread_z->contMutexThread]);
for(;inicio <= final; inicio++){
thread_z->z[inicio] = thread_z->x[inicio] + thread_z->y[inicio];
//printf("z[%u] e o valor é: %f \n", inicio, z[inicio]);
}
pthread_exit(0);
}
int main() {
setlocale(LC_ALL, "Portuguese");
//obtendo o tamanho do vetor e o número de threads que o usuário deseja
int tamanho_vetor;
int n;
while (1){
printf("Digite o tamanho do vetor: ");
scanf("%d", &tamanho_vetor);
printf("Digite o número de threads: ");
scanf("%d", &n);
if (tamanho_vetor % n != 0){
printf("O número de threads deve ser múltiplo do tamanho do vetor. \n");
}else{
break;
}
}
//inicialização dos vetores e variáveis
x =(float*) malloc(sizeof(float)*tamanho_vetor);
y =(float*) malloc(sizeof(float)*tamanho_vetor);
z =(float*) malloc(sizeof(float)*tamanho_vetor);
mutexes = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)*n);
int divisao = tamanho_vetor / n;
clock_t inicio = clock();
pthread_t thread_x[n];
pthread_t thread_y[n];
pthread_t thread_z[n];
Thread_preenche thread_preenche_x[n];
Thread_preenche thread_preenche_y[n];
Thread_soma thread_soma_z[n];
//inicialização das threads e mutexes.
for (int i = 0; i < n; ++i){
int posInicial = i*divisao;
int posFinal = i*divisao+divisao-1;
//para o x
thread_preenche_x[i].vetor = &x[0];
thread_preenche_x[i].posInicial = posInicial;
thread_preenche_x[i].posFinal = posFinal;
thread_preenche_x[i].contMutexThread = i;
//para o y
thread_preenche_y[i].vetor = &y[0];
thread_preenche_y[i].posInicial = posInicial;
thread_preenche_y[i].posFinal = posFinal;
thread_preenche_y[i].contMutexThread = i;
//para o z
thread_soma_z[i].x = &x[0];
thread_soma_z[i].y = &y[0];
thread_soma_z[i].z = &z[0];
thread_soma_z[i].posInicial = posInicial;
thread_soma_z[i].posFinal = posFinal;
thread_soma_z[i].contMutexThread = i;
printf("A thread %u processará os elementos dos vetores nas posições de %u a %u \n", i,
posInicial, posFinal);
pthread_mutex_init(&mutexes[i],NULL);
pthread_create(&thread_x[i], NULL, preencheVetores, &(thread_preenche_x[i]));
pthread_create(&thread_y[i], NULL, preencheVetores, &(thread_preenche_y[i]));
pthread_create(&thread_z[i], NULL, somaVetores, &(thread_soma_z[i]));
}
for (int i = 0; i < n; i++){
pthread_join(thread_x[i], NULL);
pthread_join(thread_y[i], NULL);
pthread_join(thread_z[i], NULL);
}
clock_t fim = clock();
float tempo_gasto = (float)(fim - inicio) / CLOCKS_PER_SEC;
//impressão dos resultados.
for (int i = 0; i < tamanho_vetor; i++){
printf("[%u] x = %f y = %f z = %f \n", i, x[i], y[i], z[i]);
}
printf("Tempo de execução: %f segundo(s). \n", tempo_gasto);
free(x);
free(y);
free(z);
free(mutexes);
#ifdef _WIN32
system("pause");
#else __linux__
system("read -p 'Press Enter to continue...\n' key");
#endif
return 0;
}
Remembering that basically, I just want to synchronize my thread that populates the vector z = x + y, with the threads that populate the vectors x and y with random values.