Можно ли использовать мьютекс для блокировки только одного элемента структуры данных? - PullRequest
2 голосов
/ 23 ноября 2011

Можно ли использовать мьютекс для блокировки только одного элемента структуры данных? например

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] одновременно? Поток блокирует всю структуру данных карты или только элемент, например карта [1] или карта [2].

спасибо

Ответы [ 4 ]

4 голосов
/ 23 ноября 2011

Если вы можете гарантировать, что никто не изменяет сам контейнер (через insert и erase и т. Д.), То, пока каждый поток обращается к другому элементу контейнера, вы должны быть хорошо.

Если вам нужна блокировка для каждого элемента, вы можете изменить тип элемента на такой, который предлагает синхронизированный доступ. (В худшем случае пара мьютексов и исходное значение.)

3 голосов
/ 23 ноября 2011

Вам нужен другой мьютекс для каждого элемента карты.Вы можете сделать это с помощью карты мьютекса или добавления мьютекса к отображаемому типу (в вашем случае это int, поэтому вы не можете сделать это без создания нового класса, такого как SharedInt)

0 голосов
/ 23 ноября 2011

Мьютексы блокируют исполняемые области, а не объекты. Я всегда думаю о блокировке любых областей кода, которые читают / изменяют объекты потока. Если объект заблокирован в области, но этот объект доступен в другой области несинхронизированного кода, вы не защищены (конечно). В вашем случае я бы заблокировал доступ ко всему объекту, поскольку вставки и чтение из контейнеров могут легко вызвать переключение контекста и, таким образом, повысить вероятность повреждения данных.

0 голосов
/ 23 ноября 2011

Mutex это все о дисциплине.Один поток может вызвать запись, а другой поток - запись1.Среда выполнения C ++ будет предполагать, что это преднамеренно.Но в большинстве случаев это не предназначен программист.Резюме - до тех пор, пока все потоки / методы следуют дисциплине (поймите критический раздел и соблюдайте его), будет последовательность.

int i=0;

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

Write1()
{
    i++;
}
...