0
The Goal of the program is to give in the command line nt=number of tasks that will be created , an integer n, and nbloco, number of interactions that each thread can have to calculate the sum of the squares of n. also there must be a buffer with the same size of nt.
I THINK THE PROBLEM WILL BE IN THE VOIDS
So far I’ve been able to do the threads spwan, but I’m having some problems with the buffer in the wheel calculations but it doesn’t show the desired results.
First I created an accessible structure
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int nbloco; /* numero de elementos do bloco a processar */
int nt; /* numero de tarefas */
int n; /* numero inteiro a processar */
int nt_somadoras; /* caso queira mais que uma somadora */
int soma_global; /* a soma total dos elementso calculados */
int items_buffer;
typedef struct {
/* This structure is passed to the threads and contains all necessary
information for computations */
pthread_mutex_t * mutex; /* Mutex */
pthread_cond_t * cond; /* Main Condition variable */
pthread_cond_t * produzir; // signaled when items are removed
pthread_cond_t * consumir; // signaled when items are added
int *buffer; /* buffer partilhado */
int *matriz; /* Matriz com os valores a calcular */
int numero_thread; /* número das threads */
int inicio; /* Elemento que deve começar o cálculo */
}estrutura_global;
void * calculadora(void *); /* Declaração da finção calculadora */
void * somadora(void *); /* Declaração da tarefa somadora */
int main(int argc, char ** arcv){
int a, i, z, x, y; /* defenição da variavel i */
/* ler dados da linha de comendos*/
nt=atoi(arcv[1]);
n=atoi(arcv[1]);
nbloco=atoi(arcv[1]);
nt_somadoras=1;
/* Verificação de dados */
/* Alocação de memorias */
estrutura_global * estrutura = malloc(sizeof(estrutura_global));
estrutura->mutex = malloc(sizeof(pthread_mutex_t));
estrutura->cond = malloc(sizeof(pthread_cond_t));
estrutura->produzir = malloc(sizeof(pthread_cond_t));
estrutura->consumir = malloc(sizeof(pthread_cond_t));
pthread_t * calculadoras = malloc(sizeof(pthread_t)*nt);
pthread_t * somadoras = malloc(sizeof(pthread_t)*nt_somadoras);
pthread_attr_t * attr = malloc(sizeof(pthread_attr_t));
estrutura->matriz = malloc(sizeof(int)*n);
estrutura->buffer = malloc(sizeof(int)*nt);
/* Inicializações */
pthread_mutex_init(estrutura->mutex,NULL);
pthread_cond_init(estrutura->cond,NULL);
pthread_cond_init(estrutura->produzir,NULL);
pthread_cond_init(estrutura->consumir,NULL);
pthread_attr_init(attr);
pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM); /* The thread competes for resources with all other threads in all processes on the system */
soma_global=0;
estrutura->numero_thread=0;
int items_buffer=0;
/* Filling arrays with numbers */
for(a=0;a<n;++a){
estrutura->matriz[a]=a+1;}
/*Preparing to spawn threads. Mutex + condition variable are used
to ensure that the thread is spawned and initialized before
altering the thread structure variables for the next thread */
/* Lock the mutex to use pthread_cond_wait */
pthread_mutex_lock(estrutura->mutex);
/* Compute the number of elements to calculate for each thread and
initialize the number to 0 */
if(nt<nbloco){
nbloco = nbloco + ((n/nt)-nbloco);}
if(nt==nbloco && nbloco==n){
nbloco = 1;}
/* Spawn threads */
for(i=0;i<nt_somadoras;++i){
pthread_create(&somadoras[i],NULL,somadora,estrutura);}
for(z=0;z<nt;++z){
pthread_create(&calculadoras[z],NULL,calculadora,estrutura);
++estrutura->numero_thread; /* Setting the thread number, start and count */
/* Here we deal with the situation when the array size is not a multiple of number of threads */
if(z==(nt-1) && n%nt){
nbloco = n-nbloco*z;}
estrutura->inicio = z*nbloco;
pthread_cond_wait(estrutura->cond,estrutura->mutex);
}
/*Unlock the mutex, it will be used by the threads to add their partial sums to the sum */
pthread_mutex_unlock(estrutura->mutex);
Here I hope the therads are finished
/* Wait until the threads are done. */
for(x=0;x<nt;++x){
pthread_join(calculadoras[x],NULL);}
for(y=0;y<nt_somadoras;++y){
pthread_join(somadoras[z],NULL);}
/* Print the result */
printf("The sum of numbers from 1 to %d is %d\n",n,soma_global);
Here I set the memory free
free(estrutura->matriz);
pthread_cond_destroy(estrutura->cond);
free(estrutura->cond);
pthread_cond_destroy(estrutura->produzir);
free(estrutura->produzir);
pthread_cond_destroy(estrutura->consumir);
free(estrutura->consumir);
pthread_attr_destroy(attr);
free(attr);
pthread_mutex_destroy(estrutura->mutex);
free(estrutura->mutex);
free(calculadoras);
free(somadoras);
free(estrutura);
return 0;
}
This is my first void of calculating tasks, they when I run they are not doing the required number of interactions. and I don’t know what it is but I don’t think they’re writing for the buffer.
void * calculadora(void * estrutura_calculadora){
int a, soma_parcial;
estrutura_global * const estrutura = estrutura_calculadora;
pthread_mutex_lock(estrutura->mutex);
int * const matriz = estrutura->matriz;
int * const buffer = estrutura->buffer;
int const numero_thread = estrutura->numero_thread;
int const inicio = estrutura->inicio;
pthread_cond_signal(estrutura->cond);
pthread_mutex_unlock(estrutura->mutex);
int const fim = nbloco + inicio;
for(a=inicio;a<fim;++a){
if(items_buffer == nt) { // full
pthread_cond_wait(estrutura->produzir, estrutura->mutex); // wait until some elements are consumed
}
soma_parcial= matriz[a]*matriz[a];
buffer[items_buffer]=soma_parcial;
printf("Sou a tarefa %d a minha soma parcial é %d e o buffer é %d\n", numero_thread, soma_parcial, items_buffer);
pthread_cond_signal(estrutura->consumir);
}
pthread_exit(NULL);
}
The second void is the task that adds up, which seems not to be working due to the reading and cleaning of the buffer, which I cannot do.
void * somadora(void * estrutura_somadora){
int c, b;
estrutura_global * const estrutura = estrutura_somadora;
pthread_mutex_lock(estrutura->mutex);
int * const buffer = estrutura->buffer;
pthread_cond_signal(estrutura->cond);
pthread_mutex_unlock(estrutura->mutex);
for(c=0;c<=n;++c){
pthread_mutex_lock(estrutura->mutex);
if(items_buffer == 0) { // empty
pthread_cond_wait(estrutura->consumir, estrutura->mutex); // wait for new items to be appended to the buffer
}
for(b=0;b<=items_buffer;++b){
soma_global+=buffer[c];
printf("Sou a tarefa somadora a soma global é %d\n",soma_global);
}
pthread_cond_signal(estrutura->produzir);
pthread_mutex_unlock(estrutura->mutex);
}
pthread_exit(NULL);
}