5

私は Stackoverflow で同様の質問をしましたが、まだ良い答えが得られません:

  1. ブーストがシグナルとスロットを実装する方法
  2. シグナルとスロットの実装方法

この信号/スロットがどのように達成されるかについて、私はかなり困惑しています。

Q1: 以下のコードから、sig が 2 つの関数 (Hello() と World()) に接続されており、関数がシリアル化された方法で呼び出されているように見えます。これは、1 つの関数 (Hello()) が別の関数(World())に入る前に完了しますか? =>シングルスレッドプログラム

Q2: マルチスレッドのシグナル/スロットを有効にする方法はありますか? (=> World() はすぐに開始されます。Hello() が完了するのを待つ必要はありません。) または、推奨されない場合は、その理由を教えてください。 ?

Boost Web サイトのサンプル コード:

struct Hello 
{
  void operator()() const { std::cout << "Hello";}
};
struct World
{
  void operator()() const { std::cout << ", World!" << std::endl;}
};

boost::signal<void ()> sig;
sig.connect(Hello());
sig.connect(World());
sig();

出力: ハロー、ワールド!

4

2 に答える 2

4

Q1:
呼び出しはシリアル化されています。信号が内部で行っていることは、大幅に単純化されています。

foreach connection:
  call handler

したがって、ハンドラーで長時間ブロックしたくありません。多くの作業を行う必要がある場合は、スレッドを作成するなどして、そこから呼び出すことができます。

Q2:
ブーストシグナル 1 はスレッドセーフではありません。シグナル2はそうですが、それでもシリアル化された呼び出しを行います。シグナルは主にイベント処理に使用されるため、ハンドラーで実際に多くの作業を行わないのが一般的なスタイルです。
したがって、それらを「並行して」呼び出すことには実際の利点はありません。一般に、必要なスレッド呼び出しのオーバーヘッドを正当化する利点はありません。

于 2009-10-19T23:09:01.393 に答える
3

Q1: あなたは正しいです。それを反映するために、あなたが参照した質問に対する私の答えを修正しました。

Q2: 何をスレッド化するかで混乱しているようです。発行/キャプチャ プロセスでは、コードを含むのはスロットです。したがって、コードを同時に実行したい場合は、スロットを異なるスレッドに配置する必要があります。

このような動作は Qt でサポートされています (実際にはブーストについては知りません) 。qt のマニュアルには、そのような動作には「キュー処理」が必要になる可能性が高いと説明されている章があります。ただし、スロットコードを実行するスレッドには「イベントループ」の概念が必要です (作業中のスレッドに「やあ、自分のことをやめて、代わりにこれをやれ!」とだけ言うことはできないからです)。

待ちたくない場合は、スロット コードでスレッドを直接生成する必要があります。そして、両方のスロットがアクセスできるコードである種の「待機」関数を使用することを忘れないでください。ところで、boost と Qt の両方に、システム スレッド ライブラリを簡単に処理できる優れたラッパーがあります。

于 2009-10-19T23:09:02.517 に答える