Необходимо ли сделать переменную pthread_mutex_t энергозависимой? - PullRequest
2 голосов
/ 21 июня 2019

В java мы обычно делаем окончательную статическую переменную блокировки так, чтобы существовала только одна ее копия (хотя я помню, что читал, что даже статические переменные могут дублироваться в стеки вызовов двух методов!)

Но яработа с Си и синхронизация данных.Я объявил переменную pthread_mutex_t, для которой N число потоков будет заблокировано для доступа к общему ресурсу.

Я не уверен, является ли эта переменная доказательством дублирования или нет (Проблема со статическими переменными вJava, который может или не может быть дублирован в стек вызовов двух методов).Потому что, если они дублируются компилятором, то, как мне кажется, блокировка может не сработать.Так нужны ли нам более радикальные модификаторы доступа, такие как «volatile», чтобы сделать его действительно единичным?

Ответы [ 3 ]

5 голосов
/ 21 июня 2019

Мало того, что это не нужно; не разрешено . Аргумент для pthread_mutex_... функций имеет тип pthread_mutex_t * и требует действительного указателя на pthread_mutex_t объект. Указатель на volatile pthread_mutex_t не преобразуется автоматически так же, как указатель на const pthread_mutex_t, потому что его нельзя использовать там, где нужен неквалифицированный. Вы можете конвертировать его с помощью приведения, но тогда у вас просто неопределенное поведение для нарушения контракта функций.

3 голосов
/ 21 июня 2019

Краткий ответ: нет.Если объявленная вами переменная является глобальной, то она будет только одна (независимо от квалификатора volatile ).Volatile обычно используется для переменных, которые могут изменяться в контексте прерывания (микроконтроллеры) или другого потока, но не самой блокировки.

Похоже, значение volatile отличаетсяв C и Java.Взгляните на: https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword

volatile ключевое слово C является квалификатором, который применяется к переменной при ее объявлении.Он сообщает компилятору, что значение переменной может измениться в любое время - без каких-либо действий со стороны кода, найденного компилятором поблизости.

0 голосов
/ 21 июня 2019

Чтобы подчеркнуть, почему это необходимо, вы можете увидеть следующий пример:

Если вы напишите что-то вроде этого:

void parallel_function(){
   //Example function, this doesn't exist, but it is good to let you understand
   pthread_mutex_is_free(&lock);

   doStuff();
}

Тогда pthread_mutex_is_free будет делать некоторые проверки, чтобы увидеть, если мьютекс свободен, прежде чем зафиксировать его. И здесь есть подвох, проблема заключается в оптимизации компилятора, потому что для него код выполняется из одного потока, поэтому он может пропустить эту проверку (мьютекс свободен), потому что он видит, что эта переменная установлена ​​перед как бесплатный и никогда не изменяемый, поэтому он всегда будет бесплатным, и это бесполезно, поэтому пропускается в скомпилированном коде. Таким образом, используя Volatile, заставить компилятор, чтобы избежать такого рода проверки, в основном говорю это, чтобы ожидать эту переменную, чтобы изменить волшебно и так, чтобы избежать статических оптимизаций.

...