Многопоточное чтение из файлов - PullRequest
0 голосов
/ 19 ноября 2018

В настоящее время я пытаюсь создать выходные данные с помощью трех отдельных программ (process1, 2 и 3) и основной программы, которую я хочу прочитать из файлов и добавить в строку.В настоящее время в моих функциях все, что я делаю, это: 1. Откройте файл, 2. прочитайте символ, 3. добавьте его в свой буфер символов и 4. распечатайте вывод.(Три процесса имеют разные интервалы времени, в которые он производит целые числа и символы).

//Function for process 1 (Every second)
void thread1_func(void) {
  char *c; //Have to use *c because second param of strcat is a char pointer
  while(1) {
    usleep(50000);
    //Reading from file
    output = fopen("output1.txt", "r");
    fscanf(output, "%c", &c); //Copy int to c
    strcat(o1_buff, &c); //strcat it to char buffer
    printf("Thread 1 file input: %s\n", o1_buff);
    fclose(output);
  }
}

//Function for process 2 (Every 30 seconds)
void thread2_func(void) {
  char *number;
  while(1) {
    usleep(50000);
    //Reading from file
    output = fopen("output2.txt", "r");
    fscanf(output, "%c", &number);
    strcat(o2_buff, &number);
    printf("Thread 2 file input: %s\n", o2_buff);
    fclose(output);
  }
}

//Function for process 3 (Every 120 seconds)
void thread3_func(void) {
  char *character;
  while(1) {
    usleep(50000);
    //Reading from file
    output = fopen("output3.txt", "r");
    fscanf(output, "%c", &character);
    strcpy(o3_buff, &character);
    printf("Thread 3 file input: %s\n", o3_buff);
    fclose(output);
  }
 }

Однако при запуске моей программы я получаю следующее сообщение об ошибке enter image description here

В чем здесь проблема?Если проблема заключается в том, что мои буферы заполняются (что я создал "char o1_buff [1024] = {'\ 0'}" и т. Д.), Тогда у меня есть отдельная функция, которую я планирую реализовать мьютексом за один раз.вывод буферов записывается в выходной файл.

1 Ответ

0 голосов
/ 19 ноября 2018

Передача комментариев в ответ.

Вы говорите о процессах и потоках - не путайте их.

Если вывы работаете с потоками POSIX, все ваши функции имеют неправильную подпись;они должны быть похожи на void *thread1_func(void *unused) { … } и должны закончить return NULL;, хотя это немного спорный вопрос, так как все они имеют бесконечные петли в них на данный момент.

1012 * Ваши претензии 1, 30 и 120 секундных интервалыне оправданы показанным вами кодом.
  • У вас, похоже, есть одна глобальная переменная FILE *output, которую потоки небрежно перезаписывают по своей прихоти.Это плохо.

  • В thread1_func() у вас есть неинициализированный указатель char *c; вместо char c; - ой!Аналогичные жалобы в двух других функциях.

Вы не показали определения глобальных переменных o1_buff и т. Д.Не ясно, будет ли основной поток обращаться к ним;если это так, у вас есть проблемы с управлением параллелизмом.

Пожалуйста, перечитайте о том, как создать MCVE ( Minimal, Complete, Verifiable Example ), и не забудьте создать MCVE, когда задаете вопросвот так.

Поскольку в этом коде нет вызова free(), невозможно начать догадываться, где возникает проблема.Похоже, что вы работаете на Mac или, возможно, на машине BSD, учитывая сообщение о сбое.

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

Будьте осторожны с глобальными переменными - особенно общими - в программировании потоков.Хотя потоки ввода-вывода POSIX защищают дескрипторы открытых файлов от помех между потоками (дополнительную информацию см. В flockfile()), они не защищают их от злоупотреблений, таких как различные вызовы fopen() в разных потоках, вызывающиепеременная, которая должна быть сброшена, независимо от того, какой поток ее использует.

Самое простое решение - сделать переменную локальной для функций потока;тогда нет помех.Или создайте три глобальные переменные.Или, в качестве альтернативы, снова используйте мьютекс или аналогичный механизм управления доступом, чтобы предотвратить взаимодействие потоков друг с другом при использовании глобальной переменной.В этом контексте (и многих других) предпочтительнее делать переменную локальной, чем альтернативы.

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