Boost库中的信号与时隙与多线程

时间:2009-10-19 22:50:46

标签: c++ multithreading boost signals-slots

我在Stackoverflow上遇到过类似的问题,但仍然无法得到一个好的答案:

  1. how boost implements signals and slots
  2. How signal and slots are implemented
  3. 我很困惑这个信号/插槽是如何实现的。

    Q1:从下面的代码中,sig连接到两个函数(Hello()和World()),似乎函数以序列化方式调用,这也意味着一个函数(Hello()) )在进入另一个函数(World())之前需要完成吗? =>单线程序

    Q2:无论如何都要启用多线程信号/插槽?(=> World()会立即启动,不需要等待Hello()完成。)或者如果不推荐,你会不会介意告诉我为什么?

    Sample codes on Boost website

    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();
    

    输出:     你好,世界!

2 个答案:

答案 0 :(得分:3)

Q1:
这些电话是序列化的。内部正在做的信号大大简化了:

foreach connection:
  call handler

因此,您不希望长时间阻止处理程序。如果你需要做很多工作,你可以从那里调用它,例如通过为它创建一个线程。

Q2:
增强信号1甚至不是线程安全的;信号2是,但仍然是序列化的呼叫。由于信号主要用于事件处理,因此在处理程序中实际上没有做太多工作是常见的风格 因此,并行调用它们没有任何实际好处,这些好处通常不能证明必要的线程调用的开销。

答案 1 :(得分:2)

Q1:你是对的。修正了您引用的my answerthe question以反映该内容。

Q2:看起来你应该对什么应该是线程感到困惑。在发射/捕获过程中,包含代码是插槽。因此,如果您想同时运行代码,则应将插槽放在不同的线程中。

Qt支持这种行为(实际上并不知道提升),qt手册中有a chapter解释说,你很可能需要对这种行为进行“排队处理”。但是你必须在执行插槽代码的线程中有“事件循环”的概念(因为你不能只告诉工作线程“嘿,不要再做你的东西了,而是这样做!”)。 / p>

如果您不想等待,则必须直接在插槽代码中生成线程。而且你不应该忘记在插槽中都可以使用某种“等待”功能。顺便说一句,boost和Qt都有很好的包装系统线程库,以便轻松实现。