Threading across multiple files

Posted by Zach M. on Stack Overflow See other posts from Stack Overflow or by Zach M.
Published on 2012-12-10T18:19:19Z Indexed on 2012/12/10 23:05 UTC
Read the original article Hit count: 148

Filed under:
|

My program is reading in files and using thread to compute the highest prime number, when I put a print statement into the getNum() function my numbers are printing out. However, it seems to just lag no matter how many threads I input. Each file has 1 million integers in it. Does anyone see something apparently wrong with my code? Basically the code is giving each thread 1000 integers to check before assigning a new thread. I am still a C noobie and am just learning the ropes of threading. My code is a mess right now because I have been switching things around constantly.

#include <stdio.h>  
#include <stdlib.h> 
#include <time.h>   
#include <string.h>
#include <pthread.h> 
#include <math.h>
#include <semaphore.h>

//Global variable declaration
char *file1 = "primes1.txt";
char *file2 = "primes2.txt";
char *file3 = "primes3.txt";
char *file4 = "primes4.txt";
char *file5 = "primes5.txt";
char *file6 = "primes6.txt";
char *file7 = "primes7.txt";
char *file8 = "primes8.txt";
char *file9 = "primes9.txt";
char *file10 = "primes10.txt";

char **fn; //file name variable

int numberOfThreads;
int *highestPrime = NULL;
int fileArrayNum = 0;
int loop = 0;

int currentFile = 0;


sem_t semAccess;
sem_t semAssign;

int prime(int n)//check for prime number, return 1 for prime 0 for nonprime
{
  int i;
  for(i = 2; i <= sqrt(n); i++)
    if(n % i == 0)
      return(0);

    return(1);
}

int getNum(FILE* file)
{
  int number;
  char* tempS = malloc(20 *sizeof(char));
  fgets(tempS, 20, file);
  tempS[strlen(tempS)-1] = '\0';
  number = atoi(tempS);


  free(tempS);//free memory for later call

  return(number);
}

void* findPrimality(void *threadnum) //main thread function to find primes
{
  int tNum = (int)threadnum;
  int checkNum;
  char *inUseFile = NULL;
  int x=1;

  FILE* file;
  while(currentFile < 10){

    if(inUseFile == NULL){//inUseFIle being used to check if a file is still being read

      sem_wait(&semAccess);//critical section     
      inUseFile = fn[currentFile];
      sem_post(&semAssign);
      file = fopen(inUseFile, "r");


      while(!feof(file)){
    if(x % 1000 == 0 && tNum !=1){ //go for 1000 integers and then wait
      sem_wait(&semAssign);
    }

    checkNum = getNum(file);
    /*
     * 
     * 
     * 
     * I think the issue is here
     * 
     * 
     * 
     */
    if(checkNum > highestPrime[tNum]){
      if(prime(checkNum)){
        highestPrime[tNum] = checkNum;
      }
    }

    x++;
      }
      fclose(file);
      inUseFile = NULL;
    }
    currentFile++;
  }
}

int main(int argc, char* argv[])
{

  if(argc != 2){ //checks for number of arguements being passed
printf("To many ARGS\n");
return(-1);
  }
  else{//Sets thread cound to user input checking for correct number of threads
    numberOfThreads = atoi(argv[1]);
    if(numberOfThreads < 1 || numberOfThreads > 10){
      printf("To many threads entered\n");
      return(-1);
    }

    time_t preTime, postTime; //creating time variables

    int i;

    fn = malloc(10 * sizeof(char*)); //create file array and initialize

    fn[0] = file1;
    fn[1] = file2;
    fn[2] = file3;
    fn[3] = file4;
    fn[4] = file5;
    fn[5] = file6;
    fn[6] = file7;
    fn[7] = file8;
    fn[8] = file9;
    fn[9] = file10;


    sem_init(&semAccess, 0, 1); //initialize semaphores
    sem_init(&semAssign, 0, numberOfThreads);

    highestPrime = malloc(numberOfThreads * sizeof(int)); //create an array to store each threads highest number

    for(loop = 0; loop < numberOfThreads; loop++){//set initial values to 0
      highestPrime[loop] = 0;   
    }

    pthread_t calculationThread[numberOfThreads]; //thread to do the work

    preTime = time(NULL); //start the clock

    for(i = 0; i < numberOfThreads; i++){
      pthread_create(&calculationThread[i], NULL, findPrimality, (void *)i);
    }

    for(i = 0; i < numberOfThreads; i++){
      pthread_join(calculationThread[i], NULL);
    }

    for(i = 0; i < numberOfThreads; i++){
      printf("this is a prime number: %d \n", highestPrime[i]);
    }
    postTime= time(NULL);
    printf("Wall time: %ld seconds\n", (long)(postTime - preTime));
  }
}

Yes I am trying to find the highest number over all. So I have made some head way the last few hours, rescucturing the program as spudd said, currently I am getting a segmentation fault due to my use of structures, I am trying to save the largest individual primes in the struct while giving them the right indices. This is the revised code. So in short what the first thread is doing is creating all the threads and giving them access points to a very large integer array which they will go through and find prime numbers, I want to implement semaphores around the while loop so that while they are executing every 2000 lines or the end they update a global prime number.

#include <stdio.h>  
#include <stdlib.h> 
#include <time.h>   
#include <string.h>
#include <pthread.h> 
#include <math.h>
#include <semaphore.h>

//Global variable declaration
char *file1 = "primes1.txt";
char *file2 = "primes2.txt";
char *file3 = "primes3.txt";
char *file4 = "primes4.txt";
char *file5 = "primes5.txt";
char *file6 = "primes6.txt";
char *file7 = "primes7.txt";
char *file8 = "primes8.txt";
char *file9 = "primes9.txt";
char *file10 = "primes10.txt";



int numberOfThreads;
int entries[10000000];
int entryIndex = 0;
int fileCount = 0;
char** fileName;
int largestPrimeNumber = 0;


//Register functions
int prime(int n);
int getNum(FILE* file);
void* findPrimality(void *threadNum);
void* assign(void *num);

typedef struct package{
  int largestPrime;
  int startingIndex;
  int numberCount;
}pack;



//Beging main code block
int main(int argc, char* argv[])
{

  if(argc != 2){ //checks for number of arguements being passed
printf("To many threads!!\n");
return(-1);
  }
  else{ //Sets thread cound to user input checking for correct number of threads
    numberOfThreads = atoi(argv[1]);
    if(numberOfThreads < 1 || numberOfThreads > 10){
      printf("To many threads entered\n");
      return(-1);
    }

    int threadPointer[numberOfThreads]; //Pointer array to point to entries

    time_t preTime, postTime; //creating time variables

    int i;

    fileName = malloc(10 * sizeof(char*)); //create file array and initialize

    fileName[0] = file1;
    fileName[1] = file2;
    fileName[2] = file3;
    fileName[3] = file4;
    fileName[4] = file5;
    fileName[5] = file6;
    fileName[6] = file7;
    fileName[7] = file8;
    fileName[8] = file9;
    fileName[9] = file10;

    FILE* filereader;
    int currentNum;

    for(i = 0; i < 10; i++){
      filereader = fopen(fileName[i], "r");
      while(!feof(filereader)){
        char* tempString = malloc(20 *sizeof(char));
        fgets(tempString, 20, filereader);
        tempString[strlen(tempString)-1] = '\0';
        entries[entryIndex] = atoi(tempString);
        entryIndex++;
        free(tempString);       
      }
    }

    //sem_init(&semAccess, 0, 1); //initialize semaphores
    //sem_init(&semAssign, 0, numberOfThreads);
    time_t tPre, tPost;



    pthread_t coordinate;

    tPre = time(NULL);
    pthread_create(&coordinate, NULL, assign, (void**)numberOfThreads);
    pthread_join(coordinate, NULL);


    tPost = time(NULL);



  }

}

void* findPrime(void* pack_array)
{
  pack* currentPack=  pack_array;
  int lp = currentPack->largestPrime;
  int si = currentPack->startingIndex;
  int nc = currentPack->numberCount;

  int i;
  int j = 0;


  for(i = si; i < nc; i++){

    while(j < 2000 || i == (nc-1)){

      if(prime(entries[i])){

    if(entries[i] > lp)

      lp = entries[i];
      }

      j++;

    }

  }
   return (void*)currentPack; 
}

void* assign(void* num)
{
  int y = (int)num;
  int i;

  int count = 10000000/y;
  int finalCount = count + (10000000%y);

  int sIndex = 0;



  pack pack_array[(int)num];
  pthread_t workers[numberOfThreads]; //thread to do the workers


  for(i = 0; i < y; i++){
    if(i == (y-1)){
      pack_array[i].largestPrime = 0;
      pack_array[i].startingIndex = sIndex;
      pack_array[i].numberCount = finalCount;
    }

    pack_array[i].largestPrime = 0;
    pack_array[i].startingIndex = sIndex;
    pack_array[i].numberCount = count;


    pthread_create(&workers[i], NULL, findPrime, (void *)&pack_array[i]);
    sIndex += count;
  }
  for(i = 0; i< y; i++)
    pthread_join(workers[i], NULL);
}




//Functions

int prime(int n)//check for prime number, return 1 for prime 0 for nonprime
{
  int i;
  for(i = 2; i <= sqrt(n); i++)
    if(n % i == 0)
      return(0);

    return(1);
}

© Stack Overflow or respective owner

Related posts about c

    Related posts about multithreading