2013-04-19 2 views
-2

У меня есть пример с мьютексом. CurrentValue - член ClassВозвращаемое значение от Mutex

int Class::NextValue() 
{ 
    mutex.lock(); 
    ++CurrentValue; 
    ++CurrentValue; 
    int localValue = CurrentValue; 
    mutex.unlock(); 
    return localValue; 
} 

Я не понимаю, почему используется localValue. Следующий код не будет работать должным образом?

... 
    mutex.unlock(); 
    return CurrentValue; 

В случае, когда return не атомное CurrentValue может изменяться во время конструктора копирования. Но в первом примере кода может быть то же самое с localValue?

ответ

2

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

C++ 11:

int Class::NextValue() 
{ 
    std::lock_guard<std::mutex> lock(mutex); 
    ++CurrentValue; 
    ++CurrentValue; 
    return CurrentValue; 
} // mutex unlocked on exiting this scope. 
+0

Но 'localValue' может измениться и между разблокировкой и возвратом? Да, я знаю о стражах. Спасибо – 2013-04-19 09:56:39

+1

@PulsatingAmbience 'localValue' является локальным для функции, поэтому, если другой поток вызывает' NextValue', он увидит другое 'localValue'. Таким образом, нет условий гонки. – juanchopanza

+0

Это означает, что есть отдельный стек вызовов для каждой темы? – 2013-04-19 10:30:53

5

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

В любом случае, код должен быть правильно записан с помощью RAII, и проблема даже не стоит о чем думать.

int Class::NextValue() 
{ 
    std::lock_guard<std::mutex> lock(mutex); 
    ++CurrentValue; 
    ++CurrentValue; 
    return CurrentValue; 
} 
+0

Но 'return localValue;' читает 'localValue' вне защиты тоже?Это то же самое, что и с 'return CurrentValue;'? – 2013-04-19 10:02:08

+2

'localValue' не используется, потому что это локальная переменная. Ничто другое не может его увидеть, а тем более писать. –

+0

'localValue' является локальным для мьютекса, функции или потока? Потому что в случае локальной функции в памяти есть только один «localValue»? – 2013-04-19 10:14:36

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