← Назад к вопросам

Параллельное чтение файла по частям

1.2 Junior🔥 131 комментариев
#Основы Go

Условие

Напишите программу для конкурентной обработки большого файла по частям.

Сигнатура

func processFileParallel(filename string, workers int, processor func(chunk []byte) error) error

Требования

  • Разбить файл на части (chunks)
  • Обрабатывать части параллельно в workers горутинах
  • Использовать worker pool для ограничения параллелизма
  • Корректно обрабатывать ошибки
  • Поддержка отмены через context

Пример использования

err := processFileParallel("large_file.txt", 4, func(chunk []byte) error {
    // обработка части файла
    return nil
})

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Параллельное чтение файла

Описание задачи

Обрабатывать большой файл параллельно:

  • Разбить на chunks фиксированного размера
  • Обрабатывать в worker pool
  • Ограничить одновременные горутины
  • Обрабатывать ошибки
  • Поддержка context отмены

Архитектура решения

Используем паттерн worker pool:

  1. Стартуем N worker горутин
  2. Читаем файл в main горутине
  3. Отправляем chunks в канал
  4. Workers обрабатывают chunks
  5. Собираем ошибки и возвращаем

Параметры

  • chunkSize: 8KB (можно 4KB до 64KB)
  • workers: количество одновременных обработчиков
  • timeout: контекст для отмены

Алгоритм

Шаг 1: Открыть файл Шаг 2: Создать буфер размера chunkSize Шаг 3: Запустить workers Шаг 4: В цикле:

  • Читать chunk из файла
  • Отправить в канал workers
  • Проверить context.Done() Шаг 5: Закрыть канал chunks Шаг 6: Дождаться завершения workers Шаг 7: Проверить ошибки

Обработка ошибок

  1. Ошибки при чтении файла
  2. Ошибки из processor функции
  3. Context отмена (timeout)
  4. Закрытие файла (defer)

Сложность

  • Time: O(n) где n - размер файла
  • Space: O(chunkSize * workers) - буферы в памяти

Оптимизация: используем sync.Pool для переиспользования буферов

Ключевые компоненты

  1. os.Open/ReadAt - чтение файла
  2. sync.WaitGroup - ожидание workers
  3. chan - передача chunks
  4. context - отмена
  5. sync.Once - гарантия one-time обработки ошибки

Worker паттерн

Каждый worker:

  1. Получает chunk из канала
  2. Вызывает processor(chunk)
  3. Обрабатывает ошибку
  4. Повторяет пока канал открыт

Мain:

  1. Закрывает канал после чтения
  2. Ждет завершения всех workers
  3. Возвращает первую ошибку если есть

Параметры оптимизации

chunkSize:

  • Меньше 4KB: слишком много syscalls
  • 8-64KB: обычный размер
  • Больше 64KB: много памяти

workers:

  • Обычно равен количеству CPU cores
  • Может быть больше если операция I/O bound
  • Минимум 1, максимум разумный лимит

Обработка контекста

При context.Done():

  1. Останавливаем чтение из файла
  2. Закрываем канал chunks
  3. Workers завершаются
  4. Возвращаем context.Err()

Распределение работы

РoundRobin (простой способ):

  • Отправляем chunks в один общий канал
  • Все workers берут из одного канала
  • Go runtime балансирует нагрузку

Есть более сложные: работа с affinity, NUMA и т.д., но это overengineering для файлов