如何防止信号2::scoped_connection 在disconnect() 中中止?

Posted

技术标签:

【中文标题】如何防止信号2::scoped_connection 在disconnect() 中中止?【英文标题】:How can I prevent signals2::scoped_connection from aborting in disconnect()? 【发布时间】:2016-05-24 22:02:27 【问题描述】:

我正在使用 boost::signals2 并且遇到了连接管理问题。我将 scoped_connections 存储在稍后修剪的列表中。但是,我发现如果拥有关联信号的对象已被销毁,则 scoped_connection::disconnect() 会中止,因为它的几个字段现在无效。

signals2::connection conn =
    client->connectRequest( RequestSignal::slot_type(
        bind( &Manager::requestRefresh, this, _1 ) ).track( client ) );
mClients.push_back( ClientConnection( client, conn ) );

客户端连接:

struct ClientConnection

    weak_ptr<Client> client;
    signals2::scoped_connection* connection;

    ClientConnection( weak_ptr<Client> aClient, signals2::connection aConnection )
    
        client = aClient;
        connection = new signals2::scoped_connection( aConnection );
    

    ~ClientConnection()
    
        delete connection;
    

Manager 类拥有这些 ClientConnections 的列表,并定期迭代并尝试删除它无法从中获取合法 shared_ptr 到客户端的条目。我现在了解到 track() 在对象过期时不会断开连接,就像我想象的那样;它只是阻止信号发射。当客户端超出范围时,scoped_connection 最终会指向一堆坏内存,并且在执行 disconnect() 时会出现预取或数据中止。

signals2 API 中是否有一些我忽略的东西可以纠正这个问题?还是我必须重新考虑我的连接管理?我知道必须从这一端保持与客户端信号的连接似乎很奇怪,但是客户端消耗的流有可能超出范围,因此在这种情况下,我需要断开管理器的插槽与客户端的连接。

【问题讨论】:

【参考方案1】:

事实证明,这是一个对象生命周期问题,而不是信号 2 问题。我使用指向范围连接的原始指针来绕过它的不可复制属性。但我忽略的是,当结构在插入列表时被复制构造时,原始结构被破坏,从而删除了指针的内存......

将其更改为共享指针可解决此问题。

【讨论】:

以上是关于如何防止信号2::scoped_connection 在disconnect() 中中止?的主要内容,如果未能解决你的问题,请参考以下文章

当iPhone锁定在iOS5上时,如何防止应用程序被发送终止信号?

Python:防止信号传播到子线程

如何防止验证样式影响工具提示

如何使用信号量锁定表?

我们应该使用带有信号量的互斥量来进行正确的同步并防止竞争条件吗?

如何在 c++ linux 中获取 3g 调制解调器信号强度?