gpt4 book ai didi

c++ - 这种编码线程安全,死锁安全吗?

转载 作者:行者123 更新时间:2023-11-30 04:00:38 25 4
gpt4 key购买 nike

下面我们有数据容器。我们希望多个线程能够搜索 Container 并获取 Data 对象。

#include <boost/thread.hpp>

using boost::shared_ptr;
using boost::mutex;
using boost::lock_guard;
using std::string;

class CData
{
public:
bool find(string& value, const string& fieldName)
{
lock_guard<mutex> guard(m_lock);
auto it=m_data.find(fieldName);
if( it!=m_data.end())
{
value=it->second;
return true;
}
return false;
}


CData(const CData& rhs)
{
lock_guard<mutex> guard(rhs.m_lock);
m_data=rhs.m_data;
}

CData& operator=( const CData& rhs )
{
if ( this == &rhs )
{
return *this;
}

mutex* lock1;
mutex* lock2;

if(this<&rhs)
{
lock1=&m_lock;
lock2=&rhs.m_lock;
}
else
{
lock1=&rhs.m_lock;
lock2=&m_lock;
}

lock_guard<mutex> guard1(*lock1);
lock_guard<mutex> guard2(*lock2);

m_data=rhs.m_data;
}



private:

std::map<string,string> m_data;
mutable mutex m_lock;
};

容器在 map 中保存共享点。不同的线程将查找容器中的对象并查找对象中的字段。

class CDataContainer
{
public:
CDataContainer* instance()
{
static CDataContainer* s_instance;
static mutex s_instanceLock;
lock_guard<mutex> guard(s_instanceLock);
if(!s_instance)
{
s_instance=new CDataContainer;
}
return s_instance;
}

void insert(const string& key, const shared_ptr<CData>& data)
{
lock_guard<mutex> guard(m_lock);
m_key2data[key]=data;
}


void erase(const string& key)
{
lock_guard<mutex> guard(m_lock);
m_key2data.erase(key);
}

bool find(shared_ptr<CData>& data,const string& key)
{
lock_guard<mutex> guard(m_lock);
auto it=m_key2data.find(key);
if( it!=m_key2data.end())
{
data=it->second;
return true;
}
return false;
}



private:
CDataContainer()

}

mutex m_lock;
std::map<string,shared_ptr<CData>> m_key2data;
};

最佳答案

也许吧,虽然到处都是互斥体,但效率可能不高。如果我可以建议一个小的修改:

class CData
{
public:
void insert(const string& key, const shared_ptr<CData>& data) const;
...
private:
const std::map<string,string> m_data;
};

现在您不需要 CData 中的任何互斥体,并且您可以更加确信它的线程安全性。多线程真正的前进方向是从常量的角度来考虑它。我建议阅读 Bartosz's blog他在其中展示了如何仅通过使用不变性来编写没有互斥锁或同步的线程安全 C++。

编辑:作为附加说明,在没有死锁的情况下获取多个互斥锁的正确方法是使用 std::lock ,如:

    std::unique_lock<std::mutex> lk1(m_lock, std::defer_lock);
std::unique_lock<std::mutex> lk2(rhs.m_lock, std::defer_lock);
std::lock(lk1, lk2);

Edit2: CDataContainer::instance 中的同步在 C++11 中也是不必要的现在可以完全安全地执行以下操作:

CDataContainer& instance()
{
static CDataContainer s_instance;
return s_instance;
}

关于c++ - 这种编码线程安全,死锁安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26196066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com