2010-03-10 2 views
3
  1. Статичные переменные, хранящиеся в стеке, аналогичны глобальным? Если да, то как они защищены, чтобы разрешить доступ только к локальному классу?Статическая и глобальная переменная в памяти

  2. В многопоточном контексте возникает опасение, что к этой памяти можно напрямую обращаться другие потоки/ядро? или почему мы не можем использовать static/global в многопроцессорной/поточной среде?

+3

Я предсказываю, что в течение следующих 10 минут у вас будет 3 оборота, несмотря на то, что их спрашивали тысячи раз. О, и я должен был сказать по крайней мере 3 ответа от людей, которые ЗНАЮТ, что это обман. – 2010-03-10 22:51:54

+1

Возможно, если бы вы не повлияли на него. – Ponkadoodle

+0

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

ответ

3

Переменные, хранящиеся в стеке, носят временный характер. Они принадлежат функции и т. Д., И когда функция возвращается и соответствующий стек стека вылетает, переменные стека исчезают вместе с ним. Поскольку глобальные объекты предназначены для доступа везде, они не должны выходить из контекста и, таким образом, сохраняются в куче (или в специальной секции данных двоичного файла), а не в стеке. То же самое относится к переменным static; поскольку они должны удерживать свое значение между вызовами функции, они не могут исчезнуть, когда функция возвращается, поэтому они не могут быть выделены в стеке.

Что касается защиты переменных static, IIRC это в основном выполняется компилятором. Несмотря на то, что переменная находится в куче, ваш компилятор знает ограниченный контекст, в котором эта переменная действительна, и любая попытка получить доступ к static вне этого контекста приведет к «неизвестному идентификатору» или подобной ошибке. Единственный другой способ получить доступ к переменной кучи неправильно, если вы знаете адрес static, и вы слепо снимаете ссылку на указатель на него. Это должно привести к ошибке доступа к памяти во время выполнения.

В многопоточной среде все еще можно использовать глобальные переменные и статические переменные. Однако вы должны быть гораздо более осторожны. Вы должны гарантировать, что только один поток может получить доступ к переменной за раз (обычно через какой-то механизм блокировки, такой как мьютекс). В случае локальных переменных static внутри функции вы должны убедиться, что ваша функция будет функционировать должным образом, если она вызывается из нескольких потоков последовательно (то есть, вызывается из потока 1, затем из потока 2, затем потока 1, затем потока 2 и т. Д.). Это, как правило, сложнее, и многие функции, которые полагаются на переменные-члены static, из-за этого не являются потокобезопасными (strtok - примечательный пример).

+1

Можете ли вы привести ссылку на поддержку «статических переменных не могут быть выделены в стеке и что они хранятся в куче» – bubble

1

Хранится статические переменные на самом стеке подобно глобал? Если да, то как они защищены, чтобы разрешить доступ только к локальному классу?

No, static относится только к длительности хранения - они могут быть глобальными или иметь локальный охват. Глобалы имеют статическое хранилище.

В многопоточном контексте возникает опасение, что эта память может быть напрямую доступна другим потокам/ядру? или почему мы не можем использовать static/global в многопроцессорной/поточной среде?

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

2

Статичные переменные, хранящиеся в стеке, аналогичны глобальным? Если да, то как они защищены, чтобы разрешить доступ только к локальному классу?

Обычно они хранятся в памяти вместе с глобалами. однако видимость имен переменных ограничивает доступ.

В многопоточном контексте возникает опасение, что эта память может быть напрямую доступна другим потокам/ядру? или почему мы не можем использовать static/global в многопроцессорной/потоковой среде?

Проблема заключается в том, что есть только одна копия статической, так что если несколько потоков изменяют переменную, один поток может вызвать изменение другого потока, чтобы быть потеряны, если не гарантии (критические секции), чтобы не допустить этого ,

+0

Что делать, если это статические данные, относящиеся к потоку? он явно не виден другим потокам, и единственный способ получить доступ к нему будет через прямую адресацию памяти, правильно? – Swapna

+0

Если вы имеете в виду это в локальном хранилище потоков, тогда нет проблем (если вы не передадите адрес на что-то еще). Если он связан с процедурой потока (например), все равно может возникнуть проблема - для нескольких экземпляров потоков возможно выполнение одной и той же процедуры потока (или других функций, вызываемых из нее). Если ваш threadproc будет запускать только один поток, вам не придется беспокоиться о защите локальной статистики от этого threadproc. –

3

Статические переменные имеют статическую продолжительность хранения, поэтому они обычно не помещаются в стек. Единственной «защитой» для них является то, что их имя имеет локальную видимость во время компиляции. Передача адреса статической переменной дает ему доступ.

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

+0

Статические переменные и глобальные переменные находятся в памяти кучи? – Swapna

+4

Не обязательно. Стандарт не определяет ни «стек», ни «кучу», поэтому неверно предполагать, что вся память принадлежит тому или другому. Обычно глобальные таблицы хранятся в секции данных, связанной с программой (и процессом). С точки зрения OS это, вероятно, было выделено из кучи, но с другой стороны, с точки зрения OS, стек был, вероятно, выделен из кучи. –