问题标签 [boost-signals2]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 如何使用 boost::signals2 存储和转发插槽?
我有一个问题,我必须比我想要的更早地实例化对象实例,因为我需要通过一些深度所有权来连接信号槽,并且我想想出一种存储和转发的方法槽,以便我可以在更接近其使用站点的位置构造对象,而不是作为成员变量这样做。
我的基本问题是我有一个进程将在单独的线程上下载更新文件并向任何感兴趣的人发送进度信号。信号本质上是:
假设progress
下面提到的函数的实现符合这个;信号本身的性质并不是很重要(尽管我大部分时间都在使用仿函数)。
信号被设置,代码被称为如下:
当您调用updater.runDownloadTask()
时,它将启动
UpdaterDownloadTask
,它启动HTTPRequest
并返回一个
HTTPResponse
。它HTTPResponse
是与网络层交互并接收数据并包含DownloadProgress
信号的部分。有了这个,我的实现看起来有点像(自下而上
HTTPResponse
,大量缩写为不特别说明性的省略方法):
所以,我的更新程序必须有一个UpdaterDownloadTask
始终存在的实例,它有一个实例HTTPRequest
,它有一个实例——HTTPResponse
只是因为我必须将插槽连接从Updater
(公共 API 入口点)转发到HTTPResponse
(信号所属的位置) .
我宁愿UpdaterDownloadTask::run()
这样实现:
This would have similar implications at the HTTPRequest level (so I
don't have to construct the HTTPResponse until I perform the request)
and overall make for a nicer data flow with strong RAII semantics. I've
previously tried defining the slots_
variable as a vector:
Yet I can only get this to work if I force the callers to call
onDownloadProgress(boost::ref(slot));
.
Has anyone done this successfully, or have a good suggestion on how to store and forward other than what I'm doing?
c++ - 是否有现有的方法来序列化 boost::signals2 信号的调用?
我想序列化 boost::signals2 信号的多线程调用,以确保有关来自对象的状态更改的通知以明确定义的顺序到达插槽。
背景
我在多线程程序中有一个具有内部状态的对象。内部状态的某些部分对程序的其他部分来说是有趣的,并且对象通过使用 boost::signals2 信号公开状态更改,类似于:
问题
如果有多个 OnEvent 处理程序的并发调用,这可能会导致侦听器以不同于实际发生更改的顺序收到有关状态更改的通知。状态本身由上面的互斥锁保护,因此实际状态是明确定义的。但是,互斥锁不能在对信号的调用中保持,因为这可能导致死锁。这意味着信号的实际调用可能以任何顺序发生,而我会要求它们以与实际发生状态更改的顺序相同的顺序被调用。
处理此问题的一种方法是从信号中删除状态,并仅通知侦听器状态已更改。然后,他们可以查询对象的状态,并获取对象在信号触发时的状态或以后的状态。在我的场景中,需要通知侦听器所有状态更改,因此此方法在这里不起作用。
我的下一个方法如下:
我没有尝试过上面的代码,所以它可能充满了错误和编译错误,但应该可以推断出我所追求的。我的直觉告诉我,我不是第一个遇到此类问题的人,我更喜欢使用经过验证的代码而不是我自己的... :) 所以我的问题是:
是否有一种预先存在的方法来实现对 boost::signals2 信号的序列化调用(例如内置到 signals2 库或通用模式中)?
c++ - boost::signals2 插槽作为非静态函数成员?
我最近一直在玩boost::signals2
学习目的,我想知道我是否可以将信号连接到位于类中的非静态插槽(就像我在 Qt 中一样)。考虑以下:
现在我想做Controller::print
一个非静态成员。boost::thread
例如,这可以使用boost::bind
; 有什么办法可以做到这一点boost::signals2
?
c++ - Boost.Signals2 销毁安全
我在对象 1 上有一个 Boost.Signals2 信号,我在对象 2 上连接到它。
如果对象 2 被破坏,信号将不会断开,这会在发出信号时导致坏事。
为了解决这个问题,我scoped_connection
在对象 2 上保留了一个。现在的问题是,如果对象 1 用信号破坏然后对象 2 破坏怎么办。
会不会造成问题?有没有更好的方法来解决一般问题?(具有来自对象 1 -> 对象 2 的连接,当它们中的一个被破坏时将断开连接)。
演示该问题的代码:
这安全吗?
c++ - 如何使用 boost::signals 来实现观察者模式?
我有一个由许多链接对象组成的应用程序,每个对象都有它们运行所需的参数。我正在使用上下文模式,以便每个对象根据构造时给出的上下文对象引用设置自己的参数。这在下面给出的简化代码示例中效果很好。
我尝试添加的下一个特性是观察者模式,这样当上下文对象中的参数发生变化时,每个订阅者对象都会收到通知并相应地更新其参数。但是,我无法确定将信号连接到插槽所需使用的语法。
理想情况下,我希望订阅者对象在构造时使用参数类注册自己,以便他们可以在对象的生命周期内更新自己(即他们必须在销毁时注销自己,或者更好的是,使用某种 RAII 技术如果超出范围,则注销自己)。下面是一个代码示例,我希望它尽可能简单。
目前的输出是
处理单元 0 参数 = 1
处理单元 1 参数 = 2
处理单元 0 参数 = 1
处理单元 1 参数 = 2
目标是让它成为...
处理单元 0 参数 = 1
处理单元 1 参数 = 2
处理单元 0 参数 = 11
处理单元 1 参数 = 22
我目前正在使用的代码如下。如果您想尝试一下,它可以以现在的形式编译得很好。请提出我需要的更改,以便将我的信号连接到插槽。随时指出任何可能导致麻烦的设计问题。提前致谢。
c++ - 错误:“无法访问在类 'boost::signals2::scoped_connection' 中声明的私有成员”?
// .cpp
(注意AddEventOccurredObserver
只是委托boost::signals2::connect()
并返回boost::signals2::connection
)
我收到以下错误。很难解释模板错误,但似乎错误是在成员声明中引起的std::vector<boost::signals2::scoped_connection> boostSignalConnections_;
我已经搜索过,我认为这可能与 scoped_connection 不可复制有关?我不知道。我使用 scoped_connection 的原因是因为这个 SO 问题: Handle connection/disconnection of many signals/slots with boost::signals2
更新
仅供参考,当我从 更改scoped_connection
为connection
时:std::vector<boost::signals2::connection> boostSignalConnections_;
。我使用的全部原因scoped_connection
是它们会在破坏时自动断开连接,而我相信 aconnection
不会。但是,我可以遍历集合并手动断开每个集合。
c++ - 在具有多线程的 Qt 应用程序中处理升压信号
我有以下问题:我们的主应用程序使用 Qt 工具包来显示窗口和用户交互。然而,我们应用程序的很大一部分对 GUI 部分一无所知。我现在创建了以下设计:
- 有一个单例类可以请求渲染给定对象(OpenSceneGraph 节点;但这与问题无关)
- 渲染请求导致单例发出信号
- 主窗口类(使用 Qt)中有一个插槽来处理对象的渲染
- 目前,该插槽仅创建一个新的文本编辑小部件并将其放置在
QMdiArea
主窗口中
但是,当我尝试创建新小部件时,应用程序不可避免地会崩溃。错误消息区域:
在仔细阅读 stackoverflow 之后,我发现了类似的问题(这些问题并不适用于这种情况)。显然,当我从另一个线程更改主窗口中的某些内容时,Qt 不喜欢它。但是,我并没有有意识地创建新线程,我认为单例(在调用后立即在 main 函数中创建QApplication()
)应该与 Qt在同一个线程中。显然,我错了。
这是一个显示我正在做的事情的最小示例(我已经提取了代码的相关部分,因此该示例并不完全有效):
我解决这个问题的尝试非常笨拙:
- 我在类中创建了一个新的Qt信号,其
MainWindow
签名与 Boost 信号相同 - 在处理 Boost 信号的插槽中,我发出新
Qt
信号,将指针传递过去 - 我现在创建了一个接收指针的新Qt插槽
当我在新插槽中打开一个新窗口时,一切正常。然而,这让我觉得非常笨拙。我是否必须像这样级联 所有Boost 信号还是有更好的方法?
c++ - 是否有一些用于模拟 Glib::Dispatcher 的 Boost 功能?
我目前正在重构一个中型软件项目。它包含一个由多个线程使用的中央内核类。目前,此类使用 aGlib::Dispatcher
来处理由多个线程发出的信号。由于重构过程的一个目标是完全摆脱glibmm
(因为Qt
将用作新框架),我试图找出一种如何使用Boost
. 我已经研究过Boost.Signals
and Boost.Signals2
,但是这些库似乎都没有提供调度程序的替代方案。
为了阐明调度员应该做什么,这里有一个来自官方文档的简短描述:
Glib::Dispatcher 的工作方式类似于 sigc::signal。但与普通信号不同的是,通知是通过管道异步发生的。这是在线程之间进行通信的一种简单而有效的方式,在具有单个 GUI 线程的线程模型中特别有用。
除了操作系统的内部 I/O 锁定之外,不涉及互斥锁。这意味着一些使用规则:
- 只有一个线程可以连接到信号并接收通知,但即使没有锁定也允许多个发送者。
- GLib 主循环必须在接收线程中运行(这通常是 GUI 线程)。
- Dispatcher 对象必须由接收线程实例化。
- 如果您想避免额外的锁定,则应在创建任何发送者线程之前实例化 Dispatcher 对象。
- Dispatcher 对象必须由接收线程删除。
- 由同一接收线程实例化的所有 Dispatcher 对象必须使用相同的主上下文。
你能给我一些正确方向的指示吗?Boost.Signals
这是我可以使用或实现的功能Boost.Signals2
吗?
编辑:正如评论者正确指出的那样,使用Qt
可能是一种选择。但是,我正在重构的类是非常低级的,我不想添加这个额外的依赖项。
c++ - 在地图中存储 boost::signals2 信号?
我面临以下问题:我想在地图中存储许多 boost::signals2
信号变量。由于这些信号是不可复制的,这显然是行不通的。我该如何解决这个问题?我已经找到了这个较旧的问题。在其中,一张海报建议将信号存储为shared_ptr
. 这是唯一的方法吗?它是否有任何缺点,或者更重要的是,它是否安全?
c++ - 为升压信号指定备用默认值2
Boost 的 signals2 库定义了一种很好的方式来传递一些扩展功能的备用参数(通过它的参数库)。当这些备用参数之一在我的代码中相当普遍时,我想制作一个帮助程序来进一步简化使用;例如,要指定备用互斥锁类型,我可以这样做:
不幸的是,这样做我也“失去”了为其他信号参数(例如组合器类型)指定替代值的能力,而没有回到冗长的语法或定义额外的元函数,例如 my_signal_with_combiner 或其他东西(这看起来很愚蠢) . 我不认为我可以使用默认模板参数值来做到这一点,因为 Combiner 的默认值需要拆分 Signature 才能获得返回类型。(当然,理想情况下,我想要适用于任何其他参数的东西,而不仅仅是组合器。)
所以,“真正的”问题是:是否有一种(简单的)方法来定义类似 signal_type 的东西,它的行为与其相同,但其中一个参数具有不同的默认值?(理想情况下,如果 Boost.Signals2 将来添加更多参数,则不需要更改。)
(另外,请不要使用 C++11。仍在使用较旧的编译器。)