Сбой защиты Mutex для продвижения реестра? - PullRequest
0 голосов
/ 28 декабря 2018

В статье о порядке памяти в c ++ 11 автор показывает пример, обосновывающий, что "lib не будет работать в c ++ 03"

for (...){
  ...
  if (mt) pthread_mutex_lock(...);
  x=...x...
  if (mt) pthread_mutex_unlock(...);
}
//should not have data-race
//but if "clever" compiler use a technique called 
//"register promotion" , code become like this:

r = x;
for (...){
    ...
if (mt) {
    x=r; pthread_mutex_lock(...); r=x;
}
r=...r...
if (mt) {
    x=r; pthread_mutex_unlock(...); r=x;
}
x=r;

Есть 3 вопроса:

1.Это промоушен только нарушает мьютексную защиту в c ++ 03? А как насчет языка c?

2.c ++ 03 потоковые библиотеки становятся неработающими?

3. Любая другая акцияможет вызвать ту же проблему?

Если это неправильный пример, то библиотеки потоков работают, а как насчет «Потоки не могут быть реализованы как библиотеки» Ханса Бема.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Для однопотокового кода состояние в абстрактной машине непосредственно не наблюдается: для объектов, которые не являются энергозависимыми, не гарантируется какое-либо конкретное состояние, когда вы останавливаете единственный поток с сигналом и наблюдаете его с помощью ptrace илиэквивалент.Единственное требование состоит в том, чтобы выполнение программы имело такое же наблюдаемое поведение, как и поведение одного возможного выполнения абстрактной машины.

Наблюдаемые - это взаимодействия с внешним миром;в основном, ввод / вывод в потоках и действия над изменчивыми объектами.

Компилятор для однопоточного кода может генерировать код, который выполняет операции с глобальными переменными или другим объектом, который оказывается разделенным между потоками, если толькосемантика одного потока уважается.Это, очевидно, тот случай, когда глобальная переменная изменена таким образом, что она возвращает свое первоначальное значение.

Например, компилятор может выдавать код, который увеличивает, а затем уменьшает переменную, по крайней мере, в некоторых редких случаях.;цель состоит в том, чтобы создать простой код за счет нескольких случайных ненужных операций.

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

0 голосов
/ 28 декабря 2018

Функции POSIX pthread_mutex_lock и pthread_mutex_unlock являются барьерами памяти, компилятор и / или ЦП не могут переупорядочивать нагрузки и сохранять их.В противном случае мьютексы были бы бесполезны.Эта статья, вероятно, неточна.

См. POSIX 4.12 Синхронизация памяти :

Приложения должны обеспечивать доступ к любой ячейке памяти более чем одним потоком управления (потоки или процессы) ограничен, так что ни один поток управления не может читать или изменять область памяти, в то время как другой поток управления может изменять ее.Такой доступ ограничен использованием функций, которые синхронизируют выполнение потока, а также синхронизирует память с другими потоками .Следующие функции синхронизируют память по отношению к другим потокам: [см. Список на веб-сайте]

...