Вы можете сосредоточиться на том, что не самая сложная часть вашего дизайна здесь.
Если очередь FIFO без какой-либо расстановки приоритетов, то вашими аксессорами будут push_back () и pop_front () - очень быстро, даже если вы не столкнетесь с проблемой использования семантики сравнения и замены (CAS), но придерживаться простого мьютекса / критической секции. Если вам нужна возможность расставить приоритеты в трафике, все становится сложнее. Если вы все же используете блокировку CAS, то (в любом случае в Windows) вы не сможете улучшить элемент shared_mutex boost :: thread, не потратив слишком много времени на выполнение этой части кода. Не уверен насчет реализаций, отличных от Windows.
Более сложная часть этой проблемы, как правило, сигнализирует незанятым рабочим потокам о начале новой работы. Вы не можете иметь их зацикливание, пока queue.front () не будет пустым, поэтому вам нужен способ, чтобы обеспечить правильное количество свободных потоков, которые будут выбраны для постановки в очередь элементов. Когда рабочий поток переходит в режим ожидания, он может проверять наличие новой работы и, если это так, выполнять, если нет, то состояние очереди должно быть установлено в состояние ожидания, чтобы следующий push_back приводил к удару «пробуждение» для перезапуска пула рабочих потоков. Эта область должна быть на 100% устойчивой ко всем не смертельным исключениям, иначе ваш процесс станет темным.
Вы управляете своими собственными потоками или используете встроенный пул потоков? Планируете ли вы иметь пул потоков динамического размера или просто создавать N потоков (возможно, настраиваемых) и запускать их до завершения процесса?
Определенно, рабочие потоки должны вести процесс регистрации рабочего элемента. Понимание того, кто владеет рабочим элементом в любой части его жизненного цикла, жизненно важно. Остановите / начните работу, и краткое изложение рабочих мест и сроки будут полезны. если ведение журнала идет медленно, отправьте его в отдельный поток через очередь «забей и забудь», но тогда нужно следить за задержкой, что сделает твой журнал менее полезным. Если вам нужна возможность внешнего управления рабочими элементами в процессе работы, то хорошая идея - отделить структуру от очереди ожидающих работ - рабочие элементы, выполняемые в процессе выполнения, проиндексированные по потокам и показывающие текущее состояние / время запуска с отдельной блокировкой. Эта структура будет O (число потоков) настолько меньше, чем «ожидающая» очередь, поэтому сканирование вряд ли станет узким местом, если длительные результирующие операции выполняются вне блокировки структуры.
Относительно производительности - что будут делать ваши рабочие потоки? если рабочие элементы будут выполняться долго, выполнять много операций ввода-вывода или выполнять другие дорогостоящие операции, то взаимодействие с очередями не является вашим узким местом в производительности, поэтому чрезмерная оптимизация этой области является относительно непродуктивной. Учитывайте в своей конструкции всю систему, а не одну маленькую область.
Это только для начала. Удачи, это не простая система для надежного проектирования.
[РЕДАКТИРОВАТЬ] на основе описания рабочего элемента.
Синтаксический анализ должен быть быстрым (хотя может потребовать дорогостоящего поиска исходных данных - трудно сказать?), А доступ к БД - реже. Похоже, настройка DB может быть вашим самым большим ударом за доллар. Если у вас нет контроля над этим, то вам просто нужно максимально уменьшить медленную БД в своем проекте. Если у вас есть возможность сделать асинхронный доступ к БД, то рабочий поток может просто выполнить достаточно работы, чтобы начать вызов БД, а затем завершить работу с обратным вызовом, позволяя другой работе начать рабочий поток. Без асинхронного доступа к БД надежный тайм-аут запроса будет трудно реализовать без какого-либо альтернативного метода перенаправления, когда ваш основной рабочий поток не ожидает завершения вызовов БД. Вам необходимо отделить ваши основные рабочие потоки от зависимости от БД, если вы не можете доверять БД для своевременного возврата или ошибки. Может быть, какой-нибудь настраиваемый или специфичный для рабочего времени тайм-аут по запросу БД? Часто библиотеки API БД допускают это.
Ваш монитор тайм-аута должен знать о состоянии рабочего элемента.Возможно, какой-нибудь виртуальный метод Cancel () на вашем рабочем месте, чтобы обеспечить гибкость в очистке элементов с истекшим временем ожидания.