是否可以使用互斥锁仅锁定数据结构的一个元素?

时间:2011-11-23 02:14:43

标签: c++ multithreading boost locking mutex

是否可以使用互斥锁仅锁定数据结构的一个元素? 例如

boost::mutex m_mutex;
map<string, int> myMap;
// initialize myMap so that it has 10 elements

// then in thread 1
{
boost::unique_lock<boost::mutex> lock(m_mutex);
myMap[1] = 5 ; // write map[1]
}
// in thread 2
{ 
    boost::unique_lock<boost::mutex> lock(m_mutex);
    myMap[2] = 4 ; // write map[1]
}

我的问题: 当线程1正在写地图[1]时,线程2可以同时写地图[2]吗? 线程锁定整个地图数据结构或仅锁定一个元素,例如, map [1]或map [2]。

感谢

4 个答案:

答案 0 :(得分:4)

如果您可以保证没有人正在修改容器本身(通过inserterase等),那么只要每个线程访问不同的元素,容器,你应该没事。

如果需要按元素锁定,可以将元素类型修改为提供同步访问的内容。 (最坏情况是一对互斥和原始值。)

答案 1 :(得分:3)

您需要为地图的每个元素使用不同的互斥锁。您可以使用互斥锁映射或向映射类型添加互斥锁(在您的情况下它是int,因此如果不创建像SharedInt这样的新类,则无法执行此操作)

答案 2 :(得分:0)

Mutex就是纪律。一个线程可以调用write,其他线程可以调用write1。 C ++运行时将假设它是有意的。但大多数案例并不是程序员的意图。总结只要所有线程/方法都遵循该规则(理解关键部分并尊重它)就会保持一致性。

int i=0;

Write()
{
    //Lock 
    i++;
    //Unlock
}

Write1()
{
    i++;
}

答案 3 :(得分:0)

互斥锁可执行区域不是对象。我总是考虑锁定任何读取/修改线程对象的代码区域。如果一个对象被锁定在一个区域内但该对象可以在另一个未同步的代码区域内访问,那么你就不安全了(当然)。在您的情况下,我将锁定对整个对象的访问权限,因为插入和从容器读取可以轻松地进行上下文切换,从而增加数据损坏的可能性。