изменчивый массив С++

У меня есть приложение с массивом указателей на MyObject объекты:

MyObject **arr;
arr= new MyObject*[10];

Приложение имеет два потока, эти потоки будут создавать и удалять new MyObject() в массив arr. Поэтому arr[n] будут все время меняться, а сами MyObject не меняются.

Должен ли я просто объявить:

volatile MyObject **arr;

Или я должен пойти с:

MyObject ** volatile arr;

заранее спасибо


person sigvardsen    schedule 28.07.2011    source источник
comment
Почему вы не объявляете части, которые не хотите изменять, как const?   -  person John    schedule 29.07.2011
comment
Вероятно, вам вообще не следует использовать volatile. Все, что он делает в этом случае, - это заставляет компилятор не оптимизировать ничего, что идет рядом с массивом, но, поскольку вам все равно нужно будет использовать атомарные или взаимосвязанные операции, это не имеет значения... за исключением того, если вы реализуете очередь быстрой перемотки вперед , и в этом случае вам не нужны атомарные операции, но volatile сильно снижает производительность, в зависимости от компилятора. В любом случае, это не добавляет волшебной потокобезопасности.   -  person Damon    schedule 29.07.2011
comment
Я согласен с 0A0D. Почему вы используете volatile? Я думаю, вам нужно сделать резервную копию и рассказать нам, какую проблему вы пытаетесь решить. Более того, вы должны остерегаться того, что многие компиляторы сильно ошибаются, когда дело доходит до volatile.   -  person David Hammen    schedule 29.07.2011
comment
Я могу ошибаться, но не volatile гарантирует, что когда поток 1 использует переменную, он загрузит ее из реальной памяти, а не только из какой-то локальной памяти. Так что, если поток 2 внезапно изменит переменную, поток 1 не будет читать локально сохраненную переменную?   -  person sigvardsen    schedule 29.07.2011
comment
@sigvardsen: Нет. Используйте инструменты, которые это делают. В Unix есть phreads; В Windows также есть библиотека потоков. И вы должны помнить, что даже при использовании в соответствии с требованиями языка компиляторы сильно ошибаются, когда дело доходит до volatile. Например, см. cs.utah.edu/~regehr/papers/ emsoft08-preprint.pdf .   -  person David Hammen    schedule 29.07.2011
comment
@David Hammen: Значит ли это, что если я использую функцию CreateThread(), предоставленную Microsoft, для создания своих потоков, она выполнит свою работу, и мне не придется беспокоиться о volatile?   -  person sigvardsen    schedule 29.07.2011
comment
Вам действительно нужно очень беспокоиться о том, что поток A захочет читать из какой-то области памяти в то же время, когда поток B хочет записать в эту область. Используйте мьютексы, блокировки чтения-записи и другие схемы синхронизации, не изменяемые. Volatile не защищает от таких событий. Volatile существует для поддержки таких вещей, как устройства ввода-вывода с отображением памяти, а не потоки.   -  person David Hammen    schedule 29.07.2011
comment
@David Hammen: В этой статье msdn.microsoft. com/en-us/library/12a04hfd(v=vs.80).aspx они используют CreateThread, но переменная по-прежнему помечена как volatile. Кроме того, в нем говорится, что ключевое слово The volatile является квалификатором типа, используемым для объявления того, что объект может быть изменен в программе чем-то, например, операционной системой, оборудованием или ПАРАЛЛЕЛЬНО ВЫПОЛНЯЕМЫМ ПОТОКОМ.   -  person sigvardsen    schedule 29.07.2011
comment
@sig: 1) MSDN не божественна, она содержит ошибки. 2) MSDN для Visual Studio в Windows. Это далеко от заявлений о volatile в C++ в целом. 3) Так что не ленитесь и слушайте экспертов: volatile бесполезна в многопоточности. Период. Извините, вы не можете заткнуть уши и сказать «ла-ла-ла» и сказать: «Посмотрите, это работает при некоторых обстоятельствах на этом одном компиляторе в этой одной операционной системе». Это не так. Используйте соответствующие инструменты.   -  person GManNickG    schedule 29.07.2011


Ответы (2)


Я думаю, вам нужно MyObject * volatile * arr;.

Обратите внимание, что volatile не является не атомарной переменной или допустимым методом синхронизации.

Изменить: Вот он: http://drdobbs.com/high-performance-computing/212701484

person Fozi    schedule 28.07.2011
comment
Я знаю об атомных вещах, и это всего лишь упрощенная версия моего кода, я учитываю синхронизацию в реальном приложении. - person sigvardsen; 29.07.2011

Я думаю, что вы используете здесь volatile неправильно. Из Википедии,

В C и, следовательно, в C++ ключевое слово volatile предназначалось для

  • разрешить доступ к подключенным к памяти устройствам
  • разрешить использование переменных между setjmp и longjmp
  • разрешить использование переменных sig_atomic_t в обработчиках сигналов.

Я заметил, что это помечено как многопоточность. У Intel есть хорошая статья о том, почему volatile — это в основном бесполезен в многопоточности.

Наконец, volatile MyObject **arr; - это правильный синтаксис - если это ваша конечная цель.

person Community    schedule 28.07.2011
comment
это Intel, а не IBM :) ... хорошая статья - person celavek; 29.07.2011