2014-02-19 4 views
2

Я вроде как новый в многопоточном программировании. Так что в моем случае у меня есть контейнер boost multi_index, который можно получить из многих потоков одновременно. Я выполняю некоторые операции поиска и вставки.Сфера применения scoped_lock

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

Так много людей используют boost scoped_lock для этой цели. Мой вопрос - это просто «область» scoped_lock?

Предположим, что у меня есть функция, как это:

void A() 
{ 
    myData data; 
    // prepare data here 

    // ******* 1 ******** 
    B(data); // assume this perform some operations 

} 

void B (myData data) 
{ 
    // do some stuff with data 
    // ******* 2 ******** 
    search(data); 
} 


void search(myData data) 
{ 
    // ******* 3 ******** 
    // start searching the data here 
} 

, так что я хотел бы получить блокировку с самого начала процесса это означает, что от процедуры A. Если я кладу boost::mutex::scoped_locklock(mutex); код на место, которое обозначен как ******* 1 ********, он также блокирует процессы в procedure B и procedure search, или мне нужно поставить замок внутри B и search? (по местам, отмеченным знаком 2 & 3). Какое место стоит 1, 2, 3 или все?

Кстати, мое приложение является единственным писателем & с несколькими типами считывателей. Итак, shared_lock делает большую разницу в моем случае или это нормально, чтобы пойти с scoped_lock?

Примечание: Я использую Visual C++ в визуальном sturdio 2008 среда

Благодаря ...

ответ

1
boost::mutex::scoped_lock lock(mutex); 

Создает объект с автоматическим хранением (ака регулярная локальная переменная). Этот объект блокирует мьютекс, который вы передаете ему при создании, и разблокирует его при уничтожении. Поскольку объект имеет автоматическое хранилище, он уничтожается (и, таким образом, мьютекс разблокируется), когда он выходит из области видимости.

В частности, это означает, что да, если вы кладете заявление scoped_lock выше на ******* 1 ******** маркера в вашем коде, мьютекс будет проходить до A() возвращается, так что исполнение B также будет защищена замком (в данном контексте).

void A() 
{ 
    myData data; 
    // prepare data here 

    boost::mutex::scoped_lock lock(mutex); 
    // whatever happens from here .... 

    doSomeStuff(); 

    B(data); // assume this perform some operations 

    doMoreStuff(); 

    // ... to here is protected by the lock 
} 

Эта идиома программирования называется RAII, для "Получение ресурса есть инициализация", и вы можете узнать больше об этом здесь: What is meant by Resource Acquisition is Initialization (RAII)?

Side-примечание: на C++ 11, в STL теперь включает в себя мьютексы и блокировки, поэтому вам не нужно использовать boost для этого. Эквивалентными данными являются:

std::mutex a_mutex; 
{ 
    std::lock_guard<std::mutex> a_lock(a_mutex); 

    // mutex is locked until the end of this scope 
} 
1

объема контекстного замка находится в пределах объема, так:

X() {

}

Y() {

подталкивание :: мьютекс :: SCO ped_lock (Mut);

X();

}

означает, что при вызове Y(), мьютекс будет заблокирован и во время исполнения X, но только тогда, когда X вызывается из Y.

+0

Что делать, если другая функция (скажем, z) вызывает внутри x? Будет ли он заблокирован, когда x вызывается из y? – user2955554

+0

hmmm Я думаю, что я уже ответил на ваш вопрос. В противном случае дайте больше описания. – wiesniak

Смежные вопросы