イベント キューを持つアプリケーションを作成しています。私の意図は、複数のスレッドが書き込み、1 つのスレッドがキューから読み取ることができるようにこれを作成し、ポップされた要素の処理を別のスレッドに引き渡して、後続のポップが再びブロックされないようにすることです。キューからアイテムをプッシュおよびポップするために、ロックと条件変数を使用しました。
void Publisher::popEvent(boost::shared_ptr<Event>& event) {
boost::mutex::scoped_lock lock(queueMutex);
while(eventQueue.empty())
{
queueConditionVariable.wait(lock);
}
event = eventQueue.front();
eventQueue.pop();
lock.unlock();
}
void Publisher::pushEvent(boost::shared_ptr<Event> event) {
boost::mutex::scoped_lock lock(queueMutex);
eventQueue.push(event);
lock.unlock();
queueConditionVariable.notify_one();
}
Publisher クラスのコンストラクター (1 つのインスタンスのみが作成されます) で、notify_one() がキャプチャされるまでループを反復する 1 つのスレッドを開始し、キューからポップされたイベントを処理する別のスレッドを開始しています。 :
コンストラクターで:
publishthreadGroup = boost::shared_ptr<boost::thread_group> (new boost::thread_group());
publishthreadGroup->create_thread(boost::bind(queueProcessor, this));
queueProcessor メソッド:
void queueProcessor(Publisher* agent) {
while(true) {
boost::shared_ptr<Event> event;
agent->getEvent(event);
agent->publishthreadGroup->create_thread(boost::bind(dispatcher, agent, event));
}
}
ディスパッチャ メソッドでは、関連する処理が行われ、処理された情報が thrift を介してサーバーに公開されます。メインスレッドにあるプログラムが存在する前に呼び出される別のメソッドでは、メインスレッドがスレッドが完了するまで待機するように join_all() を呼び出します。
この実装では、ディスパッチャー用のスレッドが作成された後、上記の while ループで、デッドロック/ハングが発生しました。実行中のコードがスタックしているようです。この実装の問題は何ですか? そして、私がやろうとしていることを行うための、よりクリーンでより良い方法はありますか? (複数の生産者と 1 つの消費者スレッドがキューを反復処理し、要素の処理を別のスレッドに引き渡す)
ありがとうございました!