fscanf не всегда продвигает указатель - PullRequest
0 голосов
/ 20 марта 2020

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

Вот моя функция, которую выполняет каждый поток:

void* readText(void* params) {
    int words_scanned = 0;
    /* Get Arguments from struct */
    struct thread_args *arguments = params;

    /* Get unique id used for setting scan start */
    pthread_mutex_lock(&lock1);
    int thread_num = arguments->thread_num++;
    pthread_mutex_unlock(&lock1);

    /* Open the file */
    FILE *file = fopen(arguments->file_name, "r"); /* Read Only */

    /* Seek to correct spot */
    int partition_size = (int) (arguments->file_size/arguments->num_threads); /* Given 1/nth of file size - the number of bytes to read */
    int current_pos = thread_num * partition_size;
    int end = current_pos + partition_size;
    fseek(file, current_pos, SEEK_SET);

    fpos_t start;
    fgetpos(file, &start);

    char bogus_string[20];
    /* Adjust pointer to beginning of next word */
    if (thread_num != 0) {
        fseek(file, -1, SEEK_CUR); /* Move Pointer back by one character */
        if (!isspace(fgetc(file))) { /* If this character is not a whitespace character */
            fscanf(file, "%s", bogus_string); /* Throw away this word and scan to the next, it will be read by the previous thread */
        }
    }

    fpos_t fp;
    int word_counter = 0;
    /* Read through the whole section assigned */
    while (ftell(file) < end) {
        if(thread_num == 1)
            printf("Current location: %ld\n", ftell(file));

        char buffer[50];
        fscanf(file, "%s", buffer);
        words_scanned++;
        if(thread_num == 1)
            printf("Scanned %s, new loc : %ld\n", buffer, ftell(file));


        /* Add string of 6 or more length to results CRITICAL SECTION */
        if (strlen(buffer) >= 6) {
            pthread_mutex_lock(&lock2);
            int* value = get(wordTable, buffer);
            if (value == NULL) {
                insert(wordTable, buffer, 1);
            } else {
                (*value)++; /* Increment Value */
            }
            fgetpos(file, &fp);
            if (!strcmp(buffer, "don’t")) {
                word_counter++;
                printf("Thread %d: %d: %s at loc: %lld\n",thread_num, word_counter, buffer, fp);
                printf("Start = %lld, End = %d\n", start,  end);
            }
            pthread_mutex_unlock(&lock2);
        }

    }

    //printf("Thread %d scanned %d words.\n", thread_num, words_scanned);
    fclose(file);
    pthread_exit(0);
}

Моя отладка заявления только для второго потока из четырех я использую для текста. Вот пример ошибки, которую я получаю с моими выходными операторами:

Current location: 3019
Scanned the, new loc : 3023
Current location: 3023
Scanned the, new loc : 3023
Current location: 3023
Scanned prince, new loc : 3030
Current location: 3030
Scanned prince, new loc : 3030

Вы можете видеть, что разделенные пробелами токены считываются, но указатель не является расширенным. Единственное, что отделяет эти два оператора отладки, - это вызов fscanf и приращение к переменной, которую я также использовал для отладки.

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

Любая помощь будет принята с благодарностью. Это моя первая многопоточная программа и только моя вторая программа на C. Это для школы.

Приветствия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...