Здравствуйте, antropolog, Вы писали:
A>А надо было всего-лишь реализовать простой паттерн — привязку продюсера к конкретному потоку. В данном случае это делается отдельной очередью на каждый поток, и помещением таски в очередь с индексом = taskID % threadNum
Такого требования нет в задании.
Таск от любого клиента может выполняться любым потоком, если только другой поток не выполняет в это время таск этого клиента.
Мне видится простой алгоритм: все таски (с ID клиента) ставятся в одну очередь, в порядке поступления.
CThreadPool имеет set "клиентов в процессе".
Потокам при создании передаётся callback на:
CTask* CThreadPool::NextTask(int& _clientId);
Где [in, out] _clientId — при вызове равен ID предыдущего клиента (например, -1 для начала), а по возвращении — текущего.
Потоки работают в бесконечном цикле NextTask() / Execute(). Ведь конечного условия не дано?
CThreadPool::NextTask() удаляет ID предыдущего клиента из set'а, перебирает лист в поисках первого ID клиента, не найденного в том set'е, добавляет его в set, удаляет из очереди и возвращает потоку.
В задании не говорится об ответственности за удаление CTask; очень может быть, что его Execute() делает delete this; перед возвращением.
Итого: 3-4 строки на функцию потока, 2-3 — на AddTask() и 15-20 на NextTask().
@ТС: к сожалению, ссылка у меня на работе не открывается (по соображениям безопасности).