Calculate Factorial Array using Thread's

1

I'm having trouble in the following exercise

  

Write a program that, given a vector with the first 5 numbers   cousins, throw 5 threads. Each of them will calculate the value of the   factorial of one of the positions of the vector and   calculated value. The main thread expects all   threads finishes, prints the vector and ends as well.

I have the following resolution

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

#define NTHREADS 5

void *Fatorial(int *array)
{
    printf("***Entrei na função fatorial***\n");
    int fat = 0, n = 0;
    for(fat = 1; n > 1; n = n - 1)
    {
        array[n] = array[n] * n;
    }
    pthread_exit(NULL);
}

int main()
{
    printf("Início da função\n");
    int *array[5] = {2,3,5,7,11};
    int i = 0,rc = 0;
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    printf("Antes do FOR\n");
    for(i = 0; i < NTHREADS; i++)
    {
        rc = array[i];
        rc = pthread_create(&tid,&attr,Fatorial,NULL);
        if (rc) 
        {              
            printf("ERROR - return code from pthread_create() is %d\n", rc);
            exit(-1);
        }
        rc = pthread_join(tid, NULL);
        if (rc) 
        {
            printf("ERROR; return code from pthread_join() is %d\n", rc);
            exit(-1);
        }
    }
    printf("Array[] = ");
    for(i = 0; i < NTHREADS; i++)
    {
        printf("%d ",array[i]);
    }
    pthread_attr_destroy(&attr);
    pthread_exit(NULL);

    return 0;
}

One of my problems is how to get the array to be calculated on the auxiliary thread (which is to calculate the factorial of an array position). Testing with the print's I can see that the program enters 5 times in the auxiliary thread so I think I'm on a correct path. I need to understand how to move the array itself.

    
asked by anonymous 29.04.2018 / 12:22

1 answer

0

As each of the threads will change a position other than the vector, it can be declared as global, and the position for the factorial calculation is reported as a in>.

Below is the commented code (with a few more changes):

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

#define NTHREADS 5

// declara o array como global
// como cada thread irá escrever em uma posição diferente
// não precisa de lock
int array[5] = { 2, 3, 5, 7, 11 };

// informa a posição do array para o cálculo
void *Fatorial(void *pos)
{
    int res = 1, fat;
    int *posicao = (int *)pos; // obtém o parâmetro da posição
    printf("***Entrei na funcao fatorial %d***\n", *posicao);
    // calcula o fatorial
    for(fat = array[*posicao]; fat > 1; fat--)
    {
         res *= fat;
    }
    // armazena de volta no array
    array[*posicao] = res;
    pthread_exit(NULL);
}

int main()
{
  printf("Inicio da funcao\n");
  int i = 0,rc = 0, pos[NTHREADS]; // Um parâmetro para cada thread
  pthread_t tid[NTHREADS]; // Uma posição para cada thread
  pthread_attr_t attr;

  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  printf("Antes do FOR\n");

  // Primeiro cria as threads...
  for(i = 0; i < NTHREADS; i++)
  {
    // cria a thread e informa a posição para cálculo
    // como parâmetro
    pos[i] = i;
    rc = pthread_create(&tid[i], &attr, &Fatorial, (void *)&pos[i]);
    if (rc)
    {
      printf("ERROR - return code from pthread_create() is %d\n", rc);
      exit(-1);
    }
  }

  // ...depois, aguarda a execução (join)
  for(i = 0; i < NTHREADS; i++)
  {
    rc = pthread_join(tid[i], NULL);
    if (rc)
    {
        printf("ERROR; return code from pthread_join() is %d\n", rc);
        exit(-1);
    }
  }
  printf("Array[] = ");
  for(i = 0; i < NTHREADS; i++)
  {
    printf("%d ",array[i]);
  }
  pthread_attr_destroy(&attr);
  pthread_exit(NULL);
  return 0;
}

Output after execution:

Inicio da funcao
Antes do FOR
***Entrei na funcao fatorial 0***
***Entrei na funcao fatorial 1***
***Entrei na funcao fatorial 2***
***Entrei na funcao fatorial 3***
***Entrei na funcao fatorial 4***
Array[] = 2 6 120 5040 39916800
    
13.05.2018 / 03:48