Multithreading 信号插槽系统中的线程安全性(C+;+;11)

Multithreading 信号插槽系统中的线程安全性(C+;+;11),multithreading,c++11,signals,slot,Multithreading,C++11,Signals,Slot,我在C++11中设计信号/插槽系统时遇到一些问题 我的主要设计目标是:简单但仍然提供一些特性和线程安全。 我个人对信号/插槽系统的看法是,发射应该尽可能快。因此,我尽量保持信号机内的插槽列表整洁。许多其他信号/插槽系统将断开的插槽保留为空。这意味着在信号发射期间需要更多的时隙来迭代和检查时隙的有效性 具体问题如下: 信号类有一个发射功能和一个断开插槽的功能: template<typename... Args> void Signal<void(Args...)>::op

我在C++11中设计信号/插槽系统时遇到一些问题

我的主要设计目标是:简单但仍然提供一些特性和线程安全。 我个人对信号/插槽系统的看法是,发射应该尽可能快。因此,我尽量保持信号机内的插槽列表整洁。许多其他信号/插槽系统将断开的插槽保留为空。这意味着在信号发射期间需要更多的时隙来迭代和检查时隙的有效性

具体问题如下:

信号类有一个发射功能和一个断开插槽的功能:

template<typename... Args>
void Signal<void(Args...)>::operator()(Args&&... args)
{
    std::lock_guard<std::mutex> mutex_lock(_mutex);

    for (auto const& slot : _slots) {
        if (slot.connection_data->enabled) {
            slot.callback(std::forward<Args>(args)...);
        }
    }
}

template<typename... Args>
void Signal<void(Args...)>::destroy_connection(std::shared_ptr<Connection::Data> connection_data)
{
    std::lock_guard<std::mutex> mutex_lock(_mutex);

    connection_data->reset();

    for (auto it = _slots.begin(); it != _slots.end(); ++it) {
        if (it->connection_data == connection_data) {
            *it = _slots.back(); _slots.pop_back();
            break;
        }
    }
}
模板
void Signal::operator()(Args&&…Args)
{
std::lock\u guard mutex\u lock(\u mutex);
用于(自动常量和插槽:\ U插槽){
if(插槽连接\u数据->已启用){
回调(std::forward(args)…);
}
}
}
模板
无效信号::破坏连接(std::共享连接数据)
{
std::lock\u guard mutex\u lock(\u mutex);
连接数据->重置();
对于(自动it=_slots.begin();it!=_slots.end();++it){
if(it->connection\u data==connection\u data){
*它=_slots.back();_slots.pop_back();
打破
}
}
}
这可以正常工作,直到有人试图建立一个连接,当我发出信号时,该连接会自动断开:

Connection con;
Signal<void()> sig;

con = sig.connect([&]() { con.disconnect(); });
sig();
连接con;
信号信号;
con=sig.connect([&](){con.disconnect();});
sig();
我这里有两个问题:

  • 可能必须重新设计emit函数,因为在迭代时可能会删除插槽
  • 同一线程中有两个互斥锁
  • 有没有可能做到这一点(可能是使用递归互斥?),或者我应该重新设计系统,使其在断开信号连接时不干扰插槽列表,只留下空插槽(就像许多其他类似项目那样)