Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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);
- /* 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 %dn",n,soma_global);
- 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;
- }
- 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 é %dn", numero_thread, soma_parcial, items_buffer);
- pthread_cond_signal(estrutura->consumir);
- }
- pthread_exit(NULL);
- }
- 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 é %dn",soma_global);
- }
- pthread_cond_signal(estrutura->produzir);
- pthread_mutex_unlock(estrutura->mutex);
- }
- pthread_exit(NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement