Является ли чтение/запись значения bool гарантией одной инструкции в C/С++

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

Ответ 1

Если объект bool считывается и записывается в одну операцию, не гарантируется стандартом С++, поскольку это помещает ограничения на базовое оборудование, которое C и С++ пытаются свести к минимуму.

Однако обратите внимание, что в сценариях с несколькими потоками вопрос о том, является ли чтение/запись типа данных Atomic, составляет только половину проблемы. Другая половина заключается в том, что изменения в каком-либо адресе отражены во всех кешах (т.е. Локальных для разных ядер) и отражены ли они во всех потоках в том же порядке. Для этого вам понадобятся барьеры памяти.

Ответ 2

Нет, это не гарантировано.

C89 и C99 не имеют возможности выразить атомарность. C11 имеет атомные объекты.

Компилятор обычно предоставляет расширения для атомарности: например. для gcc:

http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html

Лучше использовать некоторые примитивы библиотеки pthreads.

Ответ 3

например, у вас есть 2 потока, которые используют одни и те же данные.

Ваша нить 1 должна быть такой, как в следующем. имя дается как "i":

while (true) {
           flag[i] = TRUE;
           turn = j;
           while ( flag[j] && turn == j);

                 CRITICAL SECTION

           flag[i] = FALSE;

                   REMAINDER SECTION

   }

Ваша нить 2 должна быть такой, как в следующем. назовите его как "j":

while (true) {
           flag[j] = TRUE;
           turn = i;
           while ( flag[i] && turn == i);

                 CRITICAL SECTION

           flag[i] = FALSE;

                   REMAINDER SECTION

   }
Переменная flag

управляет входом в критический раздел для каждого потока.

коды выполняются следующим образом:

1- каждый поток хочет войти в критический раздел, установив его флаг true.

2-, например, поток "i" передает свой проход нитку "j", устанавливая поворот. turn variable хранит поток, который вступил в критический раздел.

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

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

4- после запуска потока j. он устанавливает свою флаговую переменную false, определяя, что не хочет входить в критический раздел.

Пятая нить я была задержана в начале цикла while.

6-, как только нить j превратится в другую нить, повернув ее начало. нить я входит в критический раздел.

этот код удовлетворяет. мьютекс, прогресс и условия ожидания границы.

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