Асинхронные потоки - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Всех с праздником. Как в 1000 асинхронных потоках построчно считать файл data.txt; проверив каждую строчку на условие. Извините, с потоками в С дел не имел, поэтому прошу Вас рыбу кода, а далее уже буду ковыряться. Заранее спасибо!

Решение задачи: «Асинхронные потоки»

textual
Листинг программы
/* Компиляция: gcc -o main main.c -lpthread -lrt */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
 
// Структура строки файла
typedef struct {
    pthread_t tid;// Идентификатор потока
    int str_num;// Номер строки, которую нужно считать
    char str[256];// Строка из файла
    char filename[256];// Имя файла
    //FILE *file_c;// Копия указателя на начало файл
} fline;
 
// Функция, возвращающая указатель на начало строки под номером str_num
// FILE *file - указатель на начало файла
FILE *start_line(FILE *file, int str_num)
{
    int i = 0;
    char c;
 
    if(str_num == 0)
        return file;
    
    while(i < str_num)
    {
        if(feof(file))
            break;
        c = fgetc(file);
        if(c == '\n')
            i++;
    }
 
    return file;
}
 
// Поток, обрабатывающий строку под номером str_num
void* read_string(void *args)
{
    fline *f_line;
    FILE *file = NULL;
 
    f_line = (fline *) args;
 
    file = fopen(f_line->filename, "r");
 
    if(!file)
    {
        printf("\nthread #%d can not open file '%s'\n", f_line -> str_num, f_line -> filename);
        return NULL;
    }
 
    file = start_line(file, f_line -> str_num);
 
    if(!fgets(f_line -> str, 255, file))// Читаем 255 символов из строки под номером str_num (вместе с символом '\n')
        printf("No line %d\n", f_line -> str_num);// Если достигнут конец файла fgets вернет NULL
    else
        printf("%d: %s\n", f_line -> str_num, f_line -> str);
 
    fclose(file);
    return NULL;
}
 
int main() {
    pthread_attr_t pattr;// Атрибуты потока
    char filename[256];// Имя файла откуда читаем
    int N = 0;// Число строк, которые хотим считать из файла
    fline *f_lines = NULL;// Указатель на структуру
    int i = 0;
 
    pthread_attr_init(&pattr);// Инициализация структуры атрибутов потока
    pthread_attr_setscope(&pattr, PTHREAD_SCOPE_SYSTEM);// для связанного потока
    pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE);// для присоединенного потока
 
    printf("File name: ");
    fgets(filename, 255, stdin);
 
    filename[strlen(filename) - 1] = '\0';// Затираем считанный функцией fgets перевод на следующую строку ('\n')
    //printf("%s",filename);
 
    printf("Number of lines = ");
    scanf("%d", &N);
 
    //printf("N = %d\n", N);
 
    if(N <= 0)
    {
        printf("N <= 0\n");
        return 1;
    }
 
    f_lines = (fline *) malloc(N * sizeof(fline));
    if(!f_lines)
    {
        printf("Malloc problem\n");
        return 2;
    }
 
    for(i = 0; i < N; i++)
    {
        f_lines[i].str_num = i;
        f_lines[i].str[0] = '\0';
        strcpy(f_lines[i].filename,filename);
        if( pthread_create(&(f_lines[i].tid), &pattr, read_string, (void *) &f_lines[i]) != 0 )// Создаем потоки
        {
            printf("Can not creat thread #%d\n", i);
            free(f_lines);
            exit(3);
        }
    }
 
    for(i = 0; i < N; i++)
        pthread_join(f_lines[i].tid, NULL);// Ожидаем завершения каждого потока
 
    free(f_lines);
 
    return 0;
}

Объяснение кода листинга программы

  1. Компиляция: gcc -o main main.c -lpthread -lrt
  2. Задача программы: чтение строк из файла указанного пользователем по номеру строки
  3. Структура строки файла:
    • pthread_t tid; // Идентификатор потока
    • int str_num; // Номер строки, которую нужно считать
    • char str[256]; // Строка из файла
    • char filename[256]; // Имя файла
    • //FILE *file_c; // Копия указателя на начало файл
  4. Функция, возвращающая указатель на начало строки под номером str_num:
    • Если str_num = 0, возвращает указатель на начало файла
    • Считывает символы из файла до достижения конца строки или конца файла
    • Возвращает указатель на начало строки
  5. Поток, обрабатывающий строку под номером str_num:
    • Открывает файл с указанным именем
    • Если файл не может быть открыт, выводит сообщение об ошибке и завершается
    • Считывает строку из файла с помощью функции fgets
    • Если строка не может быть считана, выводит сообщение об ошибке
    • Закрывает файл
  6. Основная функция программы:
    • Считывает имя файла и количество строк для чтения
    • Выделяет память для массива структур
    • Создает поток для каждой строки
    • Ожидает завершения каждого потока
    • Освобождает память
  7. Ввод: File name: test.txt
    • Вывод:
      • 1: test1
      • 2: test2
      • 3: test3
    • ...
    • N: testN
    • Где test1, test2, test3, ..., testN - строки файла test.txt

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.5 из 5
Похожие ответы