Qtでは、例えば、GUIスレッド以外のスレッドで信号を送出し、後でGUIスレッドで信号をエンキューして実行すると、ブーストでそれを行う方法はありますか?BOOSTはスレッドでシグナルを送信し、対応するスロットを別のスレッドで実行させる方法はありますか?
ありがとう
Qtでは、例えば、GUIスレッド以外のスレッドで信号を送出し、後でGUIスレッドで信号をエンキューして実行すると、ブーストでそれを行う方法はありますか?BOOSTはスレッドでシグナルを送信し、対応するスロットを別のスレッドで実行させる方法はありますか?
ありがとう
イベントループでは、boost :: asio :: io_serviceを使用します。このオブジェクト内にタスクをポストして、スレッドセーフな方法で別のスレッドにスレッドを実行させることができます:
struct MyClass
{
boost::io_service service;
void doSomethingOp() const { ... }
void doSomething()
{
service.post(boost::bind(&MyClass::doSomethingOp, this));
}
void loop()
{
service.run(); // processes the tasks
}
};
boost::signal<void()> mySignal;
MyClass myClass;
mySignal.connect(boost::bind(&MyClass::doSomething, boost::ref(myClass)));
// launches a thread and executes myClass.loop() there
boost::thread t(boost::bind(&MyClass::loop(), boost::ref(myClass)));
// calls myClass.doSomething() in this thread, but loop() executes it in the other
mySignal();
ブーストはイベントループを提供しないため、直接ではありません。
信号を別のスレッドで処理するには、別のスレッドがハンドラのキューをチェックして実行する必要があります(通常は何らかのイベントループを意味します)。 Boostは1つを提供しないので、他の場所から取得したり、書き込んだりする必要があります。
イベントループがシグナルを提供しない(またはキューを持つ簡単な解決法を実装する)場合、boost.signals2を使用することができます(boost.signalsではなく、そのバージョンがoperator+=
をオーバーライドして各ハンドラをラップして、別のスレッドで実行するようにキューに入れます。戻り値(Qtではサポートされていませんが、boostでサポートされています)を持つシグナル用に実装することも可能ですが、デッドロックを避けるように注意する必要があります。
THXこの非常に役立つサンプルです! boost :: signalは非推奨であるため、boost :: signals2 :: signal <>を使用する必要があります。 – synapse