【问题标题】:Is it possible to use mutex to lock only one element of a data structure ?是否可以使用互斥锁只锁定数据结构的一个元素?
【发布时间】:2011-11-23 02:14:42
【问题描述】:

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

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 在写 map[1] 时,线程 2 可以同时写 map[2] 吗? 线程锁定整个地图数据结构或仅锁定一个元素,例如地图[1] 或地图[2]。

谢谢

【问题讨论】:

    标签: c++ multithreading boost locking mutex


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您需要为地图的每个元素使用不同的互斥锁。您可以使用互斥锁映射或将互斥锁添加到映射类型(在您的情况下是 int,因此如果不创建像 SharedInt 这样的新类就无法做到这一点)

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • "互斥锁锁定可执行区域而不是对象" 不,锁定互斥锁。什么是“可执行区域”?
        【解决方案4】:

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

        int i=0;
        
        Write()
        {
            //Lock 
            i++;
            //Unlock
        }
        
        Write1()
        {
            i++;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-18
          • 1970-01-01
          • 1970-01-01
          • 2013-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多