简体   繁体   English

在析构函数中发出sigc ++信号是否安全?

[英]Is it safe to emit a sigc++ signal in a destructor?

My current project has a mechanism that tracks/proxies C++ objects to safely expose them to a script environment. 我当前的项目有一个跟踪/代理C ++对象的机制,以便将它们安全地暴露给脚本环境。 Part of its function is to be informed when a C++ object is destroyed so it can safely clean up references to that object in the script environment. 它的一部分功能是在C ++对象被销毁时被通知,因此它可以安全地清除脚本环境中对该对象的引用。

To achieve this, I have defined the following class: 为此,我定义了以下类:

class DeleteEmitter {
public:
    virtual ~DeleteEmitter() {
        onDelete.emit();
    }
    sigc::signal<void> onDelete;
};

I then have any class that may need to be exposed to the script environment inherit from this class. 然后我有任何可能需要暴露给从该类继承的脚本环境的类。 When the proxy layer is invoked it connects a callback to the onDelete signal and is thus informed when the object is destroyed. 当调用代理层时,它将回调连接到onDelete信号,因此在对象被销毁时被通知。

Light testing shows that this works, but in live tests I'm seeing peculiar memory corruptions (read: crashes in malloc/free) in unrelated parts of the code. 光测试表明这是有效的,但在实时测试中,我看到了代码中不相关部分的特殊内存损坏(读取:malloc / free崩溃)。 Running under valgrind suggests there may be a double-free or continued use of an object after its been freed, so its possible that there is an old bug in a class that was only exposed after DeleteEmitter was added to its inheritance hierarchy. 在valgrind下运行表明在释放对象后可能会有一个双重释放或继续使用它,因此可能在类中存在一个旧的错误,该错误仅在将DeleteEmitter添加到其继承层次结构后才会被暴露。

During the course of my investigation it has occured to me that it might not be safe to emit a sigc++ signal during a destructor. 在我的调查过程中,我发现在析构函数中发出sigc ++信号可能不安全。 Obviously it would be a bad thing to do if the callback tried to use the object being deleted, but I can confirm that is not what's happening here. 显然,如果回调试图使用被删除的对象,那将是一件坏事,但我可以确认这不是这里发生的事情。 Assuming that, does anyone know if this is a safe thing to do? 假设有人知道这是否安全? And is there a more common pattern for achieving the same result? 是否有更常见的模式来实现相同的结果?

The c++ spec guarantees that the data members in your object will not be destroyed until your destructor returns, so the onDelete object is untouched at that point. c ++规范保证在析构函数返回之前不会销毁对象中的数据成员,因此onDelete对象在此时不会受到影响。 If you're confident that the signal won't indirectly result in any reads, writes or method calls on the object(s) being destroyed (multiple objects if the DeleteEmitter is part of another object) or generate C++ exceptions, then it's "safe." 如果您确信信号不会间接导致对被销毁对象的任何读取,写入或方法调用(如果DeleteEmitter是另一个对象的一部分, DeleteEmitter多个对象)或生成C ++异常,那么它是“安全的” “。 Assuming, of course, that you're not in a multi-threaded environment, in which case you also have to ensure other threads aren't interfering. 当然,假设您不在多线程环境中,在这种情况下,您还必须确保其他线程不会干扰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM