Search code examples
cpthreadsrace-conditionfile-pointer

Race Conditions with pthreads in C


I am new to pthreads in C and I am writing a simple program that find words in several files in parallel. However, whenever I input more than one file the output varies, suggesting that there is a race condition that I am not fixing in my code. Could you please help me fix it?

The following snippet is in main, making the pthreads.

    int i = 0;
char *word = "Pluto"; //Word to be found

Message messages[argc-1];
pthread_t threads[argc-1];
for(i; i < argc - 1; i++){
    messages[i].file = argv[i + 1];
    messages[i].word = word;
    messages[i].fp   = fopen(argv[i + 1], "r");
    int  iret = pthread_create( &threads[i], NULL, threadFindWord, (void*) &(messages[i]));
}for(i = 0; i < argc - 1; i++){
    pthread_join(threads[i],NULL);
}

The function that each thread calls:

Message *msg;
msg = (Message *) ptr;

int numFound = ffindWord(msg->fp, msg->word);

printf("File %s has %i occurences of the word %s\n", msg->file, numFound, msg->word);

fclose(msg->fp);
pthread_exit(NULL);

The following is the code for finding a word in a file)

int findWord(char * file, char * word){
 char * current = strtok(file, " ,.\n");
 int sum = 0;
 while (current != NULL){
    //printf("%s\n", current);
    if(strcmp(current, word) == 0)
        sum+=1;
    current = strtok(NULL, " ,.\n");
}
return sum;
}



int ffindWord(FILE *fp, char *word){

 fseek(fp, 0, SEEK_END);
 long pos = ftell(fp);
 fseek(fp, 0, SEEK_SET);
 char *bytes = malloc(pos);
 fread(bytes, pos, 1, fp);
 bytes[pos-1] = '\0';

 int sum = findWord(bytes, word);

 free(bytes);
 return sum;
 }

For clarification, the problem is that I get different results upon consecutive runs of the program. A call $programname file1 file2 Prints different results than a same call called right after. Note, however, that the program works when only one file is passed.

Any help is appreciated.


Solution

  • strtok keeps an internal pointer that is global... use strtok_r.