我有一个recursive_mutex案件,我正试图解决。这是一段解释问题的代码。
void OnConnectionDisconnected()
{
boost::lock_guard<boost::mutex> lock ( m_mutexConnectionSet );
IPCSyncConnectionSharedPtrSet::iterator it = m_IPCSyncConnectionSet.find(spConnection);
if ( it != m_IPCSyncConnectionSet.end())
{
m_IPCSyncConnectionSet.erase(*it);
}
}
void ShutdownServer()
{
boost::lock_guard<boost::mutex> lock ( m_mutexConnectionSet );
IPCSyncConnectionSharedPtrSet::iterator it = m_IPCSyncConnectionSet.begin();
for (; it != m_IPCSyncConnectionSet.end(); )
{
if (*it)
{
IPCSyncConnectionSharedPtr spIPCConnection = (*it);
it++;
//This call indirectly calls OnConnectionDisconnected and erase the connection.
spIPCConnection->Disconnect();
}
else
{
++it;
}
}
}在多个线程(n)上调用OnConnectionDisconnected,以及在连接处于活动状态或断开连接时,只在一个线程上调用ShutdownServer。ShutdownServer遍历所有连接,并在每个连接上调用断开连接,这间接地调用了OnConnectionDisconnected,在这里我实际上删除了连接。在访问m_IPCSyncConnectionSet之前,我已经锁定了互斥锁,因为连接集在其他线程中被修改。
我需要在上面的示例代码中使用recursive_mutex,因为当调用关机时,互斥锁在同一个线程上被锁定了两次。
有人能建议我如何解决上述问题并避免recursive_lock吗?如本文所示,recurive_mutex将杀死您,http://www.fieryrobot.com/blog/2008/10/14/recursive-locks-will-kill-you/
谢谢,
发布于 2014-11-14 22:05:46
在ShutdownServer()中使用容器的临时副本。除了锁定问题之外,迭代由另一个函数修改的容器也不是一个好主意(即使这种特定的容器类型在擦除元素时不会使所有迭代器失效,这样的代码也会非常脆弱和不必要地复杂)。
void ShutdownServer()
{
boost::lock_guard<boost::mutex> lock ( m_mutexConnectionSet );
auto connections = m_IPCSyncConnectionSet;
lock.unlock();
for (auto it = connections.begin(); it != connections.end(); ++it)
if (*it)
(*it)->Disconnect();
}现在,您需要不关心锁,也不关心迭代器的有效性。
https://stackoverflow.com/questions/26929150
复制相似问题