Если задача удобно делится на части (можно разделить на независимые работы по номерам как описано в коментариях) то что-либо разрабатывать для этого не нужно.
Учесть занятость машины и запустить на ней задачу - вопрос нескольких строк кода.
Например: в linux есть утилита parallel, ей просто даешь список команд в виде текстового файлика, а она их запускает параллельно с указанным количеством одновременно запущенных процессов, по завершению одного тут же запускает следующий. Никакого контроля за работой нет (т.е. ошибки обрабатывать самостоятельно). Соответственно, настраиваешь беспарольный ssh на машины в сети, затем генерируешь текстовый файл где каждая строка вида
ssh случайный_сервер команда
и отдаешь его parallel с указанием количества машин -j N (на самом деле если задачи занимают только один поток и на одной машине можно их несколько запускать, то нужно будет посчитать сумму потоков, в этом случае все сложнее, ведь современные процессоры уже не дают линейного увеличения от количества ядер даже в идеальном случае, потребуются бенчмарки). Этот подход не идеален но максимально простой. В качестве развитие этого - список команд генерируется не заранее а на лету, каждая следующая команда дает сервер, нагрузка на который в последние секунды была минимальной, в командной строке это все будет красиво выглядеть с использованием пайпов:
command_generator | parallel -j 100 >> parallel.log 2>> parallel.err
Т.е. одна машина у тебя будет управляющей, все остальные - воркеры, ssh ставится на любую ос, а благодаря wsl даже не придется заметно переписывать код
p.s. Почти наверняка задача требует доступ к данным, которые по сети могут не очень эффективно передаваться (да и многопоточный доступ к данным редко бывает эффективный) поэтому нужно продумать систему кеширования данных, в т.ч. заранее (в linux и windows есть механизмы, разные, с оговорками, иногда проще самому в коде этим заниматься). Результаты тоже нужно куда то записывать, если поток большой, то лучше пусть сначала, по возможности, данные собираются на машинах в сети, там где они получались, позже можно их собрать воедино.
p.p.s. настоятельно рекомендую делать так чтобы воркеры в данной реализации самостоятельно обрабатывали ошибки, вплоть до вывода в stdout/stderr, иначе разбирать кашу вывода parallel будет сложно