[Edit: упс, я ответил за C ++ вместо C. Но C11 чем-то похож на C ++ 11: он также имеет «длительность хранения потока» и также использует «видимый» в обоих смыслах, которые я опишу ниже , Так что ответ для обоих одинаков. До стандартов C (++) 11 у Posix и других потоковых моделей были глобальные переменные с локальным хранилищем потоков в течение многих лет.]
Определить «видимый» [*].
Память «видима» в том смысле, что если у вас есть адрес объекта, вы можете получить к нему доступ из другого потока. Возможно, с неопределенным поведением, если вы создаете гонку данных.
Глобалы со статической продолжительностью хранения также «видимы» в том смысле, что имя глобала относится к одному и тому же объекту во всех потоках.
Глобалы с продолжительностью хранения потоков имеют отдельный объект для каждого потока, а имя относится к объекту, принадлежащему потоку, в котором выполняется код. Таким образом, они не «видны» различным потокам по имени, но сам объект по-прежнему доступен, если вы решите передать адрес из одного потока в другой.
Автоматические переменные даже не «видны» по имени в потоке в том же из любой области, кроме той, в которой они определены. Имя автоматической переменной относится к объекту, созданному для текущий вызов функции. Если функция рекурсивная, может быть более одного такого вызова на поток, каждый со своим собственным набором автоматических переменных с одинаковыми именами. Если функция вызывается одновременно из разных потоков, то каждый из них имеет свои автоматические переменные. Таким образом, имена не «видны» из разных потоков. Опять же, сами объекты доступны.
[*] В стандарте C ++ 11 1.10 использует слово «видимый» в смысле видимой памяти, а не в смысле имени, ссылающегося на один объект в разных потоках / областях. Но это формально не определяет слово. Он также использует «видимый» в том смысле, что имя находится в области видимости в 3.3.2 / 2, а в другом месте использует «видимый» по крайней мере в двух других контекстах, которые я нашел до сих пор.