Дизайн, который вы хотите, довольно прост;Я думаю, что вы, вероятно, сможете написать нужный код и заставить его работать через час или два.Поиск сторонней библиотеки для реализации этого, вероятно, является излишним (если только я не неправильно понимаю проблему).
В частности, для каждого «рабочего» потока вам нужна структура данных FIFO (например, std :: queue)Mutex и механизм, который «главный» поток может использовать, чтобы сигнализировать потоку о необходимости пробуждения и проверке структуры данных на наличие новых сообщений (например, переменной условия, семафора или даже пары сокетов, которую рабочий блокирует при чтении, и мастер может отправить байт, чтобы разбудить рабочего).
Затем, чтобы отправить задачу в определенный рабочий поток, мастер будет делать что-то вроде этого (псевдокод):
struct WorkerThreadData & workerThread = _workerThreads[threadIndexIWantToSendTo];
workerThread.m_mutex.Lock();
workerThread.m_incomingTasksList.push_back(theNewTaskObject);
workerThread.m_mutex.Unlock();
workerThread.m_signalMechanism.SignalThreadToWakeUp(); // make sure the worker looks at the task list!
... и каждый рабочий поток будет иметь цикл событий, подобный следующему:
struct WorkerThreadData & myData = _workerThreads[myWorkerIndex];
TaskObject * taskObject;
while(1)
{
myData.m_signalMechanism.WaitForSignal(); // block until the main thread wakes me up
myData.m_mutex.Lock();
taskObject = (myData.m_incomingTasks.length() > 0) ? myData.m_incomingTasks.pop_front() : NULL;
myData.m_mutex.Unlock();
if (taskObject)
{
taskObject->DoTheWork();
delete taskObject;
}
}
Это никогда не заблокирует главный поток (в течение значительного промежутка времени), так как Mutex удерживается только оченькратко кем-либо.В частности, рабочие потоки не удерживают мьютекс во время работы над объектом задачи.