Могу ли я использовать boost :: threadpool как «потокобезопасную очередь»? - PullRequest
9 голосов
/ 06 января 2010

Что мне действительно нужно, так это на самом деле многопоточная структура очереди, где несколько клиентов продолжают сбрасывать данные в очередь, а один рабочий поток продолжает обрабатывать и выдавать очередь

Существует ли какое-либо устоявшееся решение в STL или Boost?

Теперь я думаю об использовании Boost :: threadpool для этого. Просто установите количество параллельных потоков равным 1, входной параметр функции задачи изменяется каждый раз, когда приходит новое сообщение от клиента. Имеет ли это смысл, есть ли какое-то ограничение, которого я здесь еще не ожидал?

Ответы [ 3 ]

12 голосов
/ 06 января 2010

В boost есть класс очереди сообщений , вот что вам нужно: потокобезопасная очередь.

Очереди сообщений - широко используемая концепция межпроцессного взаимодействия. Очередь сообщений является поточно-ориентированной очередью, ключевая особенность которой заключается в том, что она блокирует чтение из пустой очереди и ожидает появления в ней данных. В этом классе повышения также поддерживаются синхронизированные ожидания, а также блокирование записи, если очередь заполнена.

9 голосов
/ 06 января 2010

Если вам нужна такая структура в приложении с одним процессом, boost :: asio :: io_service должно быть достаточно. Вот пример рабочего класса с использованием boost :: thread и boost :: asio :: io_service.

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

class IWorkerThreadJob
{
    public:
        virtual ~IWorkerThreadJob(){};
        virtual void execute() = 0;
};


class BoostBasedWorkingBox
{
    public:

        BoostBasedWorkingBox():
            m_IOServiceWork(m_IOService), // Give some work to io_service or else it will simply return from ::run method .
            m_WorkerThread(boost::bind(&boost::asio::io_service::run, &m_IOService))
        {}

        ~BoostBasedWorkingBox()
        {
            m_IOService.stop();
            m_WorkerThread.join();
        }

        void processJob(IWorkerThreadJob* pJob)
        {
            m_IOService.post(boost::bind(&IWorkerThreadJob::execute,pJob));
        }   

    protected:
        boost::thread m_WorkerThread;
        boost::asio::io_service m_IOService;
        boost::asio::io_service::work m_IOServiceWork;


}

Использование: - Реализуйте интерфейс IWorkerThreadJob. Вызовите метод processJob из нескольких клиентов.

Здесь boost :: asio :: io_service действует как потокобезопасная очередь.

2 голосов
/ 06 января 2010

Если вы работаете в Windows, вы можете использовать concurrent_queue в ppl.h (новинка для VS2010). Если у вас нет Windows, вы можете использовать concurrent_queue.h в стандартных блоках Intel.

У Энтони Уильямса также есть очередь на основе условной переменной в его блоге , что хорошо.

...