2

イベント キューを持つアプリケーションを作成しています。私の意図は、複数のスレッドが書き込み、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 つの消費者スレッドがキューを反復処理し、要素の処理を別のスレッドに引き渡す)

ありがとうございました!

4

1 に答える 1

1

関数は永久に実行され、それqueueProcessorを実行しているスレッドは決して終了しないようです。その関数によって作成されたすべてのスレッドは、それぞれの作業を行って終了しますが、このスレッド ( で作成された最初のスレッド) には、停止する方法がないループがありますpublishthreadGroupwhile(true)したがって、への呼び出しjoin_all()は永久に待機します。その関数がループを終了して戻るようにトリガーする他のフラグ変数を作成できますか? それでうまくいくはずです!

于 2013-03-26T07:05:16.150 に答える