Проектирование многопоточности, pthread, которая принимает файл и устанавливает N количество потоков, чтобы помочь отсортировать все простые числа - PullRequest
0 голосов
/ 02 ноября 2018

Я написал код, который в конечном продукте предполагает взять файл и использовать многопоточность, чтобы помочь найти все простые значения. К сожалению, это не работает, как запланировано, мой код выглядит следующим образом:

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

#define maxIntArraySize 10000

struct sum_struct{
  long long answer;
  int * takeNum;
};


/// primality test, if n is prime, return 1, else return 0
int isPrime(int64_t n)
{
     if( n <= 1) return 0; // small numbers are not primes
     if( n <= 3) return 1; // 2 and 3 are prime
     if( n % 2 == 0 || n % 3 == 0) return 0; // multiples of 2 and 3 are not primes
     int64_t i = 5;
     int64_t max = sqrt(n);
     while( i <= max) {
         if (n % i == 0 || n % (i+2) == 0) return 0;
         i += 6;
     }
     return 1;
}

//Thread function to generate the # of primes in said thread
void* sum_runner(void* arg)
{
  struct sum_struct *arg_struct = (struct sum_struct*) arg;

  long long sum = 0;
  int countTakeNum = sizeof(arg_struct->takeNum)/sizeof(int);
  for(int p = 0; p <= countTakeNum; p++) {
    if( isPrime(arg_struct->takeNum[p]) == 1) {sum = sum + 1;}
  }
    arg_struct->answer = sum;
    pthread_exit(0);
}

// Takes out the first requires values
int *takeOut(int * list, int div)
{
  static int r[100];
  for (int h = 0; h < div; h++){
    r[h] = list[h];
  }
  return r;
}

// Main Function
int main( int argc, char ** argv)
{

    int nThreads = atoi(argv[1]);
    int listOfNums[maxIntArraySize];
    int currentSize = 0;
    int listCounter = 0;
    /// count the primes
    printf("Counting primes using %d thread%s.\n", nThreads, nThreads == 1 ? "s" : "");
    int64_t count = 0;
    while( 1) {
        int64_t num;
        if( 1 != scanf("%ld", & num)) break;
        //printf("%d\n",num);
        listOfNums[listCounter] = num;
        currentSize += 1;
        listCounter += 1;
        //if( isPrime(num)) count ++;
    }

    struct sum_struct args[nThreads];
    int * removeNums = listOfNums;
    int divider = currentSize/nThreads;
    int lastThread = nThreads -1;

    int takeOutSize = 0;

    //first initialize the takeOuts
    for (int j = 0; j < nThreads; j++){
      if(j == lastThread){
        args[j].takeNum = removeNums;
      }else{
        args[j].takeNum = takeOut(removeNums,divider);
        removeNums = &removeNums[divider];
      }
    }


    // Launcher Thread
    pthread_t tids[nThreads];
    for (int i = 0; i < nThreads; i++){
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&tids[i], &attr, sum_runner, &args[i]);
    }

    for (int i = 0; i < nThreads; i++) {
      pthread_join(tids[i], NULL);
      printf("\nSum for thread %d is %11d\n", i, args[i].answer);
      count += args[i].answer;
    }


    //int test = 5%3;
    //printf("%d",test);
    //return 0;

    printf("Found %ld primes.\n", count);

    return 0;
}

Чтобы пояснить, что делает, в основном мой код countPrimes.c примет файл и примет 1 аргумент int. Таким образом, код будет выглядеть так: компилировать: gcc countPrimes.c -o2 -o count -lm -lpthread пробег: ./count < test.txt 5 где test.txt содержит содержимое: 1 2 3 4 5 6 7 8 9 10 100 101 102 103 104 105 106 107. Вернемся к тому, что мой код желает сделать, это использовать многопоточность, чтобы каждый поток занимал total amount of nums / # of threads. Таким образом, в этом случае это будет 18 / 5, поэтому все потоки будут принимать 3 индекса массива (они удаляют их из массива OG), за исключением последнего массива, который будет принимать все, что осталось в массиве. После того, как это все сделано, он запускает запуск потока в p_thread tids, каждый поток будет отправлен в функцию sum_runner и сканирует все значения в данном takeNum, и он будет использовать isPrime, чтобы выяснить, какие из них простые , В приведенном выше случае мне следует ожидать 7 простых чисел, только я этого не делаю, и я попробовал практически все, начиная с отладки и заканчивая оператором печати между строк, чтобы увидеть, какие ошибки я генерирую, но я не могу найти проблема, я мог бы действительно помочь.

...