Все никак не додумаю правильную архитектуру отвечающую целям.
База:
Приложение будет выполнять различные по типу таски.
Каждый таск перед его запуском будет отправлен в тредпул и в итоге выполнен в каком-то треде.
Таску, при необходимости, перед его запуском, указываются окружение и целевые обьекты, с которыми он будет проводить манипуляции.
На завершение таска можно подписаться сигналом/каллбеком.
С выше описаным у меня проблем и непоняток нет. Едем дальше.
Цели:
Большое количество тасков разных типов обусловлено необходимостью сегментировать задачи на максимально маленькие. Что позволит выполнять параллельно больше работы.
Делегирование мелких задач маленьким обьектам (таскам) подразумевает что таски должны быть в состоянии вызывать другие таски (сабтаски) и ожидать их завершения.
Львиная доля одновременно существующих и выполняющихся тасков будут одного типа. Но они будут работать с разными данными.
В целом, это тоже не вызывает проблем в реализации.
Подводные камни:
Вижу два пути:
а) создавать на каждый чих новый обьект таска, сетить ему цели и окружение и запускать его в работу, по окончании он будет удален.
б) создавать таск нужного типа только в том случае, если нет свободного, закончившего предыдущую работу таска, иначе возвращать вопрошающему свободный таск, который с новыми сетом и окружением будет отправлен в работу, но по завершении не будет удален, а отметит себя свободным, чтобы быть переиспользованым.
Так как жизнь там будет бить ключем, то, постоянные выделения и освобождения памяти мне совершенно не нравятся. Отсюда родился второй вариант. Но тут возникает необходимость блокировки состояния каждого таска.
Атомики отпали сразу, т.к. состояние комплексное и поведение сильно зависит от типа таска.
Мьютексы/фьютексы/семафоры, да. Но, взяв самое медленное (мьютекс) возникает вопрос - не будут ли блокировки медленнее созданий-удалений?
Кстати, первый вариант не отменяет необходимость блокировки. Пусть лишь в меньшем количестве мест.
Комплексно:
Свободные таски надо хранить в списке, по списку надо бежать, искать.
Принимать решение о создании таска нужного типа если нет еще ни одного такого или все такие сейчас заняты.
Чтобы узнать свободен ли таск нужно его сначала залочить. И так каждый в цикле.
Делать много списков где каждый хранит только конкретный тип (а типов дохрена, на крайняк группу близких типов?) тасков?
И, думается мне, это не преждевременная оптимизация, а лишь желание сделать сразу правильно, чтобы потом не переписывать много.
Да, надо бы тесты погонять. Не будут они сильно зависеть от проца, оси и прочего окружения?
В любом случае, я выговорился и хочу спросить вашего совета. Ой деды то наверное об этом где-то писали скорее всего.
Дай колбаски хлеб доесть, а?