Фон
У меня есть очень большой файл двоичных данных (20+ ГБ), который мне нужно проанализировать, обработать данные и записать вывод. У меня очень мало опыта работы с такими большими объемами данных, и, хотя у меня возникли небольшие проблемы с концепцией, как с этим справляться, у меня есть идея. Примечание. Входные данные содержат ряд записей, извлеченных из мэйнфрейма IBM, поэтому они отформатированы следующим образом:
Первые 4 байта каждой записи (строка / строка) - это RDW (слово дескриптора записи). RDW содержит длину записи (включая RDW). Из-за RDW, хотя файл представляет собой один постоянный поток байтов, я знаю, где заканчивается каждая запись. Я мог бы перевести этот двоичный файл в текстовый файл, преобразовав каждые два байта в его шестнадцатеричное представление, а также добавить символ новой строки в конце записи, но я боюсь, насколько большим будет двоичный файл размером более 20 ГБ, если переводится так.
Поскольку я хочу оставить файл в виде двоичного файла, у меня есть одна идея, как поступить:
- Чтение файла последовательно с использованием одного «основного» потока.
- Как только мастер достиг конца записи (используя информацию, найденную в RDW), он порождает новый «рабочий» поток, передавая потоку данные, которые он прочитал из файла.
- Рабочий поток анализирует данные, обрабатывает данные и выводит их куда-то. (Я думаю, что буду размещать данные в базе данных SQLite.)
- Пока рабочий поток работает, главный поток продолжает чтение файла, а когда он заканчивает чтение другой записи, он порождает второй рабочий поток для работы со второй записью. Это продолжается до тех пор, пока все записи не будут обработаны.
Проблема
К сожалению, я вижу проблему. Чтение «главного» потока будет работать намного быстрее, чем потоки, которые он порождает, что, боюсь, будет создано слишком много потоков. Чтобы предотвратить это, я вообразил это решение (в псевдокоде):
record = file.ReadRecord()
if(numberOfRunningWorkerThreads < MAX_THREADS)
SpawnWorkerThread(record);
else
WaitUntil(numberOfRunningWorkerThreads < MAX_THREADS)
Однако я понятия не имею, как реализовать такую функциональность, особенно это последнее условие else
. Я новичок в многопоточности и асинхронности, и я даже не уверен, в чем разница между этими двумя терминами.
Кто-нибудь может указать мне правильное направление?