многопоточность — локальные переменные и потоки C ++ (не thread_local)

Что такое модели памяти C ++ 98 и C ++ 11 для локальных массивов и взаимодействия с потоками?

я не ссылаясь на C ++ 11 thread_local ключевое слово, которое относится к глобальным и статическим переменным.

Вместо этого я хотел бы узнать, каково гарантированное поведение потоков для массивов, которые выделяются во время компиляции. Под временем компиляции я подразумеваю «массив массива [100]», который отличается от распределения с использованием новый [] ключевое слово. я не имею в виду статический переменные.

Например, допустим, у меня есть следующая структура / класс:

struct xyz { int array[100]; };

и следующая функция:

void fn(int x) {
xyz dog;
for(int i=0; i<100; ++i)  { dog.array[i] = x; }
// do something else with dog.array, eg. call another function with dog as parameter
}

Это безопасно звонить п () из нескольких потоков?
Кажется, что модель памяти C ++ такова: все локальные нестатические переменные и массивы расположены в стеке, и что каждый поток имеет свой собственный стек. Это правда (т.е. официально ли это часть стандарта)?

6

Решение

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

8

Другие решения

C ++ 98 ничего не сказал о потоках. Программы, иначе написанные на C ++ 98, но использующие потоки, не имеют значения, определенного в C ++ 98. Конечно, для потоковых расширений имеет смысл предоставлять стабильные частные локальные переменные потокам, и они обычно это делают. Но могут существовать потоки, для которых это не так: например, процессы, созданные vfork в некоторых системах Unix, в результате чего родитель и потомок будут выполняться в одном и том же стековом фрейме, так как v в vfork означает не клонировать адресное пространство, а vfork также не перенаправляет новый процесс на другую функцию.

В C ++ 11 есть поддержка потоков. Локальные переменные в отдельных цепочках активации в отдельных потоках C ++ 11 не мешают. Но если вы выходите за пределы языка и выкручивать vfork или что-то похожее на него, тогда все ставки отключены, как и раньше.

Но здесь кое-что. C ++ теперь имеет замыкания. Что если два потока оба вызывают одно и то же замыкание? Тогда у вас есть два потока с одинаковыми локальными переменными. Замыкание подобно объекту, а его захваченные локальные переменные — как члены. Если два или более потоков вызывают одно и то же замыкание, то у вас есть де-факто многопоточный объект, члены которого (т.е. захваченные лексические переменные) являются общими.

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

2

По вопросам рекламы [email protected]