消費者/生産者の問題で、マルチスレッド コードを boost::asio とスレッド プールに置き換えることができるようにするという考えです。現在、各コンシューマー スレッドはboost::condition_variable
、プロデューサーがキューに何かを追加すると、notify_one
/notify_all
を呼び出してすべてのコンシューマーに通知します。では、(潜在的に) 1,000 人以上の消費者がいる場合はどうなるでしょうか? スレッドはスケーリングしません!
を使用することに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()
orを呼び出しますasync_condition_variable::notify_all()
。各コンシューマーのハンドルが呼び出され、条件に基づいて動作するか、async_condition_variable::wait(...)
再度呼び出します。これは実現可能ですか、それとも私はここで夢中ですか? これがスレッドプールで実行されるという事実を考えると、どのような種類のロック (ミューテックス) を実行する必要がありますか?
PS: はい、これは質問というより RFC (Request for Comments) です :)。