我该选择哪个C++信号/槽库?

39

我想在一个不使用QT的项目中使用信号/槽库。我的要求很基本:

  1. 连接具有任意数量参数的两个函数。
  2. 信号可以连接到多个槽。
  3. 手动断开信号/槽连接。
  4. 良好的性能- 应用程序是基于帧的(即不是基于事件的),我想在每一帧中使用这些连接。

我已经阅读了libsigc++和Boost.Signals的比较。我也知道Boost.Signals的性能不佳。但我知道还有其他库,仍然不确定应该选择哪个库。

有没有信号/槽库的推荐?


有没有头文件实现的解决方案?您知道是否有使用标准库函数/类型的实现吗?我们正在使用boost::signals,但希望摆脱这个相当大的依赖。 - nietras
链接已失效... - ManuelSchneid3r
@ManuelSchneid3r 谢谢,幸运的是它仍然可以从archive.org获取。 - kshahar
11个回答

18

首先,尝试使用boost::signal。在你的特定情况下的应用程序中尝试之前,不要假设它速度不够快。

如果它不够高效,也许像FastDelegate这样的东西会适合你的需求?(我没有尝试过,但听说在一些boost::signal似乎不适合的情况下是一个很好的解决方案)。

无论如何,如果在你的应用程序中每帧都使用信号,将其替换为更简单的东西可能会更值得,比如容器,其中包含将在每帧调用的对象/函数。Signal更多的是为了允许立即管理“事件”,而不是使循环周期动态化(允许更改每帧调用的函数)。 (我有自己的解决方案(更新:现在非常古老和陈旧),我在游戏和其他一些地方大量使用,例如性能方面没有问题,因此类似的东西可能有所帮助)。


你的解决方案的 Google Code 链接已经失效。 - RegularlyScheduledProgramming
@RegularlyScheduledProgramming 谢谢,我已经更新了链接并将其移至Github,但现在它有点过时了。我使用的是更现代的东西,但它不是开源的,也不是设计成通用的,而是针对我正在开发的游戏特定的。 - Klaim

15

Gamedev.net论坛上的非常快的事件库

最近在对一些代码进行性能测试时,我惊讶地发现boost::signals函数排在了前面。对于那些不知道的人来说,boost::signals是一个非常有用的信号/槽库,可与boost::bind一起使用,用于类似于C#中所见的基于委托的事件处理。它稳健、功能丰富、灵活。但我发现,它也是非常、非常慢的。对于许多使用boost::signals的人来说,这没关系,因为他们很少调用事件。但是我每个对象每帧都要调用几个事件,结果是可预见的。

因此我编写了自己的事件库。虽然相对不那么灵活和功能丰富,但针对大多数人实际使用事件的方法进行了优化。事件调用速度比boost::signals快15到80倍。

查看链接。


5
这是未来观众的固定链接。 http://www.gamedev.net/topic/456646-very-very-fast-event-library/ - Joel Verhagen

5

最近接手了一个项目,发现connect在我们的项目目标中产生了太多的开销。经过性能分析,发现信号中使用了互斥锁,在我们的信号使用中不需要这个锁。根据文档,成功地用虚拟互斥锁替换了它。这个互斥锁“速度非常慢”,所以请确保你需要它。这对于其他浏览此帖子的人可能有用。

原始代码: typedef boost::signals2::signal_type<void()>::type signal_type;

新代码: typedef boost::signals2::signal_type<void(), boost::signals2::keywords::mutex_type<boost::signals2::dummy_mutex> >::type signal_type;


5
你列出的这两个是我知道的唯二值得关注的选项。从我所看到的一切来看,libsigc++在性能方面处于领先地位。正如你在比较中看到的那样,有些情况下boost的语法更漂亮一些,但只是稍微好看一点而已。
我个人使用过libsigc++,并对其感到满意。似乎更多的项目在使用Libsigc++。快速查看我的软件包管理器时,列出了更多than 100个项目依赖于libsigc++2。仅仅这一点就足以扭转平衡,特别是考虑到性能优势和其他显著差异的缺乏。
我建议使用libsigc++2。

另外还有一个针对libsigc++的额外项目,它是线程安全的:libSigC++ Extras - Adri C.S.

4
我会选择Sigslots,我试过其他一些替代品(如boost、libsig++和FastDelegates),但似乎没有一个能够以自动对象销毁的方式将函数绑定在一起并保持匿名。Sigslots对我们来说非常适用,因为它的C++代码易于阅读,速度快,简单,而且不会妨碍工作。需要注意的是,如果你想从多个库中使用它,则可能需要添加:
COREEXTERN template class COREIMPEXP has_slots<SIGSLOT_DEFAULT_MT_POLICY>;

为避免已定义对象相关的链接问题。

1
我也喜欢这个版本。为了使其与Clang和libc++兼容,我不得不应用一些在Sourceforge论坛中找到的补丁并进行一些自己的调整:https://github.com/catnapgames/SigSlot - Tomas Andrle
似乎这个程序有内存泄漏。 - Jichao

3

我以前使用过libsigc++,使用起来相当简单。我认为它不会有太多的性能损失,事实上,在一些地方,我喜欢使用槽而不是函数指针。

需要注意的一件事是,截至我上次使用(2年前),它被限制在通过连接传递的最多六个参数。

我没有使用boost库的经验,所以无法帮助您。


3

我曾使用过boost signals2库,但发现它非常慢。构造带有boost signals的对象时,99%的处理器时间被boost signals堆栈占用。即使只是使用一个简单的槽位进行信号发射,它的开销也非常大。我尝试了libsigc++,它明显更快。Libsigc++似乎非常快速和灵活。
创建了40000个对象,其中包含9个boost signals和9个libsigc++ signals:



1

1

我没有使用过libsig++,但我已经了解了它。我的信号和槽的先前经验来自Qt和一点来自Boost。如果您没有其中任何一个可用,则可以尝试使用我的信号和槽库(ksignals),该库存在于嵌入式代码(无动态内存分配)和“正常”的C ++代码(连接时进行动态内存分配)。

您可以在以下网址找到它:www.kjellkod.cc/signalandslots

在该页面上,您还可以找到比较:KSignals与Boost signals。

就速度而言,ksignals非常快,并且代码极其轻巧。它应该非常易于使用、理解和修改(如果需要)。

祝你好运 问候 Kjell H


0

另一个选项可以是YSignalSlot。我用过它。我认为它非常不错。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接