Сито Эратосфена с многопоточностью в C / Linux - PullRequest
0 голосов
/ 10 июня 2019

В настоящее время я работаю над расчетом сита Эратосфена с использованием многопоточности C.

Цель состоит в том, чтобы сначала создать основной поток, который использует функцию разделения, чтобы разделить исследование чисел на несколько потоков.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>

void *creat_thread(int *nbThreads);

void *SieveEratosthenes(int *tailleTab);

int* tab;
int sizeTab;
int nbTachesParThread=0;

int main(void)
{
  int nbThreads;
  int n;
  do{
    printf("Enter an integer > 1 :  ");
    scanf("%d", &n);
  } while(n<2);


  sizeTab = n+1;
  tab = (int*)malloc(tailleTab*sizeof(int));
  for (unsigned int i=0; i<tailleTab; i++)
  {
    tab[i] = 1;
  }

  do{
    printf("Enter a number positive number of threads : ");
    scanf("%d", &nbThreads);
  } while(nbThreads<1);

  pthread_t threadPrincipal;

  if (pthread_create(&threadPrincipal, NULL, creat_thread, NULL)) {
    perror("pthread_create");
    return EXIT_FAILURE;
  }

  if (pthread_join(threadPrincipal, NULL)) {
    perror("pthread_join");
    return EXIT_FAILURE;
  }

  printf("The Prime numbers are : \n");
  for(unsigned int i=0; i<sizeTab; i++)
  {
    if(tab[i]==1)
    {
      printf("%d\n", (i));
    }
  }


}

void *creat_thread(int *nbThreads)
{

  int nbTachesParThread = (int) sqrt(sizeTab) / nbThreads;
  pthread_t* threads = (pthread_t*)malloc(nbThreads*sizeof(pthread_t));

  int plageThreadi = nbTachesParThread;

  for(int i = 0; i < nbThreads; ++i)
    pthread_create (&threads[i], NULL, SieveEratosthenes, plageThreadi);
    plageThreadi += nbTachesParThread;
}

void *SieveEratosthenes(int *plageThread)
{


  for( int i=(plageThread - nbTachesParThread); i<=plageThread; i++)
  {
    if (tab[i] == 1)
    {
      for (int j = i*i; j<sizeTab; j += i)
      {
        tab[j]=0;
      }
    }
  }

}


Я пытался реализовать код, но у меня возникла ошибка во время выполнения:

segmentation error (core dumped)  

Ответы [ 3 ]

0 голосов
/ 10 июня 2019

Я изменил свой код, так что на самом деле у меня больше нет кода ошибки, но как только я ввел 2 переменные (число для вычисления + количество потоков), программа запускается, но ничего не отображается.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>


void *creat_thread();

void *SieveEratosthenes();

int* tab;
int sizeTab = 0;
int nbTachesParThread=0;
int nbThreads = 0;
int plageThreadi = 0;
int plageThreadPrecedent = 0;

int main(void)
{
  int n;
  do{
    printf("Enter an integer > 1 :  ");
    scanf("%d", &n);
  } while(n<2);


  sizeTab = n+1;
  tab = (int*)malloc(sizeTab*sizeof(int));
  for (unsigned int i=0; i<sizeTab; i++)
  {
    tab[i] = 1;
  }

  do{
    printf("Enter a number positive number of threads : ");
    scanf("%d", &nbThreads);
  } while(nbThreads<1);

  pthread_t threadPrincipal;

  if (pthread_create(&threadPrincipal, NULL, creat_thread, NULL)) {
    perror("pthread_create");
    return EXIT_FAILURE;
  }

  if (pthread_join(threadPrincipal, NULL)) {
    perror("pthread_join");
    return EXIT_FAILURE;
  }

  printf("The Prime numbers are : \n");
  for(unsigned int i=0; i<sizeTab; i++)
  {
    if(tab[i]==1)
    {
      printf("%d\n", (i));
    }
  }
}

void *creat_thread()
{

  int nbTachesParThread = (int) sqrt(sizeTab) / nbThreads;
  pthread_t* threads = (pthread_t*)malloc(nbThreads*sizeof(pthread_t));

  int plageThreadi = nbTachesParThread;

  for(int i = 0; i < nbThreads; ++i)
    {
      pthread_create (&threads[i], NULL, SieveEratosthenes, NULL);
      pthread_join(threads[i], NULL);
      plageThreadPrecedent = plageThreadi;
      plageThreadi += nbTachesParThread;
    }

  for(int i = 0; i < nbThreads; ++i)
      {
        pthread_join(threads[i], NULL);
      }
  pthread_exit(NULL);
}

void *SieveEratosthenes()
{
  for(int i=(plageThreadPrecedent); i<=plageThreadi; i++)
  {
    if (tab[i] == 1)
    {
      for (int j = i*i; j<sizeTab; j += i)
      {
        tab[j]=0;
      }
    }
  }
  pthread_exit(NULL);
}

0 голосов
/ 10 июня 2019

Я последовал вашему совету и создал структуру, которая будет содержать переменные, которые будут использоваться всеми потоками.

Однако я заметил, что иногда это работает (хорошо отображает простые числа), но иногда не работает и отображает либо только 0, либо все числа от 0 до i.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>


void *creat_thread(void* arg);

void *SieveEratosthenes(void* arg);

struct param
{
  int* tab;
  int sizeTab;
  int nbTachesParThread;
  int nbThreads;
  int plageThreadi;
  int plageThreadPrecedent;
};

int main(void)
{
  struct param p;

  int n;
  do{
    printf("Enter an integer > 1 :  ");
    scanf("%d", &n);
  } while(n<2);


  p.sizeTab = n+1;

  p.tab = (int*)malloc(p.sizeTab*sizeof(int));
  for (unsigned int i=0; i<p.sizeTab; i++)
  {
    p.tab[i] = 1;
  }

  do{
    printf("Enter a number positive number of threads : ");
    scanf("%d", &p.nbThreads);
  } while(p.nbThreads<1);

  pthread_t threadPrincipal;

  if (pthread_create(&threadPrincipal, NULL, (void*)creat_thread, &p)) {
    perror("pthread_create");
    return EXIT_FAILURE;
  }
  if (pthread_join(threadPrincipal, NULL)) {
    perror("pthread_join");
    return EXIT_FAILURE;
  }

  printf("The Prime numbers are : \n");
  for(unsigned int i=0; i<p.sizeTab; i++)
  {
    if(p.tab[i]==1)
    {
      printf("%d\n", i);
    }
  }
}

void *creat_thread(void* arg)
{
  struct param *args = (void*)arg;
  args->nbTachesParThread = (int) sqrt(args->sizeTab) / args->nbThreads;
  pthread_t* threads = (pthread_t*)malloc(args->nbThreads*sizeof(pthread_t));

  args->plageThreadi = args->nbTachesParThread;

  for(int i = 0; i < args->nbThreads; ++i)
    {
      pthread_create (&threads[i], NULL, (void*)SieveEratosthenes, &(*args));
      args->plageThreadPrecedent = args->plageThreadi;
      args->plageThreadi += args->nbTachesParThread;
    }

  for(int i = 0; i < args->nbThreads; ++i)
      {
        pthread_join(threads[i], NULL);
      }
  pthread_exit(NULL);
}

void *SieveEratosthenes(void* arg)
{
  struct param *args = (void *)arg;
  for(int i=(args->plageThreadPrecedent); i<=args->plageThreadi; i++)
  {
    if (args->tab[i] == 1)
    {
      for (int j = i*i; j<args->sizeTab; j += i)
      {
        args->tab[j]=0;
      }
    }

  }
  pthread_exit(NULL);
}
0 голосов
/ 10 июня 2019

Вверху упоминания о проблеме в моем комментарии есть еще что исправить:

1-я из всех функций PThread должна иметь тип void *(*)(void*). Используемые в коде имеют тип void *(*)(int*). Не хорошо.

Во-вторых, код пропускает присоединение к рабочим потокам, поэтому поток распределения заканчивается после создания всех рабочих, затем он присоединяется к main(), который затем получает доступ к переменным, над которыми рабочие, скорее всего, все еще работают, вызывая неопределенное Поведение будет так, а затем заканчивается, заканчивая процесс. Завершение процесса отменяет все рабочие потоки.

...