Мне было интересно, есть ли у кого-нибудь хорошие предложения по дизайну для очереди заданий, которая уведомляет функцию processJob (), когда задачи> 0. Я использую Boost и c ++ и просто пытаюсь получить общее представление о таком дизайне. Благодарю.
Я бы побежал processJob()
в отдельном потоке, который использует «переменную условия», чтобы определить, работает ли он; и при добавлении чего-либо в очередь, уведомив, что c.v.
Логика цикла выглядит примерно так:
boost::unique_lock<boost::mutex> lock(mymutex);
while (!terminate)
{
lock.lock();
while (!Q.empty())
jobCV.wait(lock);
pItem = Q.pop();
lock.unlock();
pItem->process();
}
Помните, что добавление элементов в очередь также должно блокироваться тем же мьютексом. Кроме того, вам нужно пройти тест до этого wait()
для сигнала, который установит terminate
; и настройка этого сигнала также необходимо вызвать notify()
на в.в.
Если вы уже используете библиотеку boost, вам будет удобно использовать boost :: asio. объект io_service может использоваться для управления очередью заданий, поскольку он гарантирует, что обратные вызовы будут вызываться в порядке их размещения. и никаких проблем с блокировками, если вы запускаете io_service только в одном потоке. Пример кода:
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <cstdlib>
int job_number = 0;
struct Job
{
virtual void run() { std::cout << "job " << ++job_number << " done" << '\n'; }
virtual ~Job() {}
};
class Processor
{
private:
boost::asio::io_service ioserv_;
boost::asio::io_service::work work_;
boost::thread thread_;
public:
Processor() : ioserv_(), work_(ioserv_) {
}
void run() {
ioserv_.reset();
thread_ = boost::thread (boost::bind(&boost::asio::io_service::run, &ioserv_));
}
void stop() {
ioserv_.stop();
}
~Processor() {
stop();
if (thread_.get_id() != boost::thread::id())
thread_.join();
}
void processJob(boost::shared_ptr<Job> j)
{
j->run();
}
void addJob(boost::shared_ptr<Job> j)
{
ioserv_.post(boost::bind(&Processor::processJob, this, j));
}
};
int main()
{
Processor psr;
psr.run();
for (int i=0; i<10; ++i)
psr.addJob(boost::shared_ptr<Job>(new Job));
sleep(1);
return 0;
}