← Назад к вопросам
Параллельное чтение файла по частям
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:
- Стартуем N worker горутин
- Читаем файл в main горутине
- Отправляем chunks в канал
- Workers обрабатывают chunks
- Собираем ошибки и возвращаем
Параметры
- chunkSize: 8KB (можно 4KB до 64KB)
- workers: количество одновременных обработчиков
- timeout: контекст для отмены
Алгоритм
Шаг 1: Открыть файл Шаг 2: Создать буфер размера chunkSize Шаг 3: Запустить workers Шаг 4: В цикле:
- Читать chunk из файла
- Отправить в канал workers
- Проверить context.Done() Шаг 5: Закрыть канал chunks Шаг 6: Дождаться завершения workers Шаг 7: Проверить ошибки
Обработка ошибок
- Ошибки при чтении файла
- Ошибки из processor функции
- Context отмена (timeout)
- Закрытие файла (defer)
Сложность
- Time: O(n) где n - размер файла
- Space: O(chunkSize * workers) - буферы в памяти
Оптимизация: используем sync.Pool для переиспользования буферов
Ключевые компоненты
- os.Open/ReadAt - чтение файла
- sync.WaitGroup - ожидание workers
- chan - передача chunks
- context - отмена
- sync.Once - гарантия one-time обработки ошибки
Worker паттерн
Каждый worker:
- Получает chunk из канала
- Вызывает processor(chunk)
- Обрабатывает ошибку
- Повторяет пока канал открыт
Мain:
- Закрывает канал после чтения
- Ждет завершения всех workers
- Возвращает первую ошибку если есть
Параметры оптимизации
chunkSize:
- Меньше 4KB: слишком много syscalls
- 8-64KB: обычный размер
- Больше 64KB: много памяти
workers:
- Обычно равен количеству CPU cores
- Может быть больше если операция I/O bound
- Минимум 1, максимум разумный лимит
Обработка контекста
При context.Done():
- Останавливаем чтение из файла
- Закрываем канал chunks
- Workers завершаются
- Возвращаем context.Err()
Распределение работы
РoundRobin (простой способ):
- Отправляем chunks в один общий канал
- Все workers берут из одного канала
- Go runtime балансирует нагрузку
Есть более сложные: работа с affinity, NUMA и т.д., но это overengineering для файлов