这个想法是能够在消费者/生产者问题上用boost :: asio和线程池替换多线程代码。目前,每个消费者线程等待boost::condition_variable
- 当生产者向队列添加内容时,它会调用notify_one
/ notify_all
来通知所有消费者。现在当你(可能)拥有1k +消费者时会发生什么?线程不会扩展!
我决定使用boost::asio
,但后来遇到了它没有条件变量的事实。然后async_condition_variable
诞生了:
class async_condition_variable
{
private:
boost::asio::io_service& service_;
typedef boost::function<void ()> async_handler;
std::queue<async_handler> waiters_;
public:
async_condition_variable(boost::asio::io_service& service) : service_(service)
{
}
void async_wait(async_handler handler)
{
waiters_.push(handler);
}
void notify_one()
{
service_.post(waiters_.front());
waiters_.pop();
}
void notify_all()
{
while (!waiters_.empty()) {
notify_one();
}
}
};
基本上,每个消费者都会拨打async_condition_variable::wait(...)
。然后,制作人最终会调用async_condition_variable::notify_one()
或async_condition_variable::notify_all()
。将调用每个消费者的句柄,并根据条件采取行动或再次致电async_condition_variable::wait(...)
。这是可行的还是我在这里疯了?应该执行什么样的锁定(互斥),因为这将在线程池上运行?
P.S。:是的,这更像是一个RFC(征求意见)而不是一个问题:)。
答案 0 :(得分:3)
列出事件发生时需要完成的事项。具有向该列表添加内容的功能以及从该列表中删除内容的功能。然后,当事件发生时,让一个线程池在现在需要完成的作业列表上工作。您不需要专门等待事件的线程。
答案 1 :(得分:1)
Boost :: asio可能有点难以理解。至少,我很难做到这一点。
您不需要让线程等待任何事情。当他们没有任何工作要做时,他们会自己做。似乎看起来像你想要做的那些例子已经将工作发布到每个项目的io_service。
以下代码的灵感来自this link。它实际上打开了我的眼睛,你可以用它做很多事情。
我确信这不是完美的,但我认为它给出了一般的想法。我希望这会有所帮助。
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
class ServerProcessor
{
protected:
void handleWork1(WorkObject1* work)
{
//The code to do task 1 goes in here
}
void handleWork2(WorkObject2* work)
{
//The code to do task 2 goes in here
}
boost::thread_group worker_threads_;
boost::asio::io_service io_service_;
//This is used to keep io_service from running out of work and exiting to soon.
boost::shared_ptr<boost::asio::io_service::work> work_;
public:
void start(int numberOfThreads)
{
boost::shared_ptr<boost::asio::io_service::work> myWork(new boost::asio::io_service::work(io_service_));
work_=myWork;
for (int x=0; x < numberOfThreads; ++x)
worker_threads_.create_thread( boost::bind( &ServerProcessor::threadAction, this ) );
}
void doWork1(WorkObject1* work)
{
io_service_.post(boost::bind(&ServerProcessor::handleWork1, this, work));
}
void doWork2(WorkObject2* work)
{
io_service_.post(boost::bind(&ServerProcessor::handleWork2, this, work));
}
void threadAction()
{
io_service_.run();
}
void stop()
{
work_.reset();
io_service_.stop();
worker_threads_.join_all();
}
};
int main()
{
ServerProcessor s;
std::string input;
std::cout<<"Press f to stop"<<std::endl;
s.start(8);
std::cin>>input;
s.stop();
return 0;
}
答案 2 :(得分:0)
如何使用boost :: signals2?
它是一个线程安全的boost :: signals分支,它允许你的客户端订阅回调信号以便发出。
然后,当在io_service调度作业中异步发出信号时,将执行所有已注册的回调(在发出信号的同一线程上)。