2013-09-05 3 views
3

Я хочу знать, что является хорошей практикой в ​​использовании объектов, хранящихся в общей памяти. Параметры у меня есть в моем уме являются:Объект C++ хранится в общей памяти (функция volatile member?)

  1. Добавить неустойчивыми к каждому функции членов объектов, хранящихся в совместно используемой памяти
  2. Скопируйте все данные из/в общей памяти на каждой итерации.
  3. Доступ к общей памяти без изменчивости.

Позвольте мне объяснить проблему, что у меня есть:

У меня есть два процесса, работающие на Linux на FPGA. Они обмениваются данными через разделяемую память. Поскольку они блокируют друг друга двоичным семафором, только один процесс выполняет свою работу за раз. Компилятор - g ++ 3.4.x. Мой текущий код является то, как показано ниже:

struct MyTime 
{ 
    int32 dayNumber; 
    int32 milliSecOfDay; 
    void convert(double* answer); 
}; 
struct MyData 
{ 
    double var1; 
    MyTime time; 
}; 
volatile MyData* ptr; 
ptr = (volatile MyData*)shmat(shmid, NULL, 0); 

double answer; 
ptr->time.convert(&answer); //< ERROR(*) 

*: ошибка: передача const volatile TimeTTJ2000' as это аргумент `BOOL TimeTTJ2000 :: get_Tu_UT1 (двойной &, Const int32 &, Const int32 &) сопзЬ» отбрасывает Отборочные

(Приведенный выше код просто поясняется. Сообщение об ошибке из моего реального кода, в котором размер MyData намного больше.)

Чтобы удалить эту ошибку, мне кажется, что мне придется определить другую функцию-член, такую ​​как

MyTime::convert(double* answer) volatile; 

Но мне кажется смешным, что я должен добавить «изменчивость» ко всем функциям библиотек, которые не обязательно являются моими.

Чтобы избежать «волатильности» повсюду, я думаю, что я могу скопировать все данные в разделяемой памяти в локальную систему сразу после разблокирования одного процесса и записать обратно в разделяемую память непосредственно перед блокировкой процесса. Таким образом, меня не волнует изменчивость, но все-таки это мудрая вещь?

Или я могу получить доступ к данным разделяемой памяти, не используя волатильность на первом месте? Это облегчило бы мою жизнь. (У меня есть небольшой опыт в разделяемой памяти и нестабильной. Я не очень уверен, когда летучий требуются. Конечно, я знаю основы, как, летучей оптимизация угнетает.)

+2

Я настоятельно рекомендую вам использовать 'boost :: interprocess' для общей памяти, а не напрямую обращаться к низкоуровневому API-интерфейсу общей платформы для платформы. –

+0

Я использую старый компилятор: 'microblaze-uclinux-g ++ (GCC) 3.4.1 (PetaLinux 0.20 Build -rc1 050607)' Для последнего boost :: interprocess требуется GCC> = 4.1. Вы по-прежнему рекомендуете мне получить более старую версию boost :: inteprocess и использовать ее в моей программе? – user22097

+1

OK - если у вас нет другого выбора, кроме как использовать этот очень старый компилятор, вам, возможно, придется придерживаться своего первоначального плана и перейти непосредственно к API общей памяти - вы все равно можете посмотреть исходный код boost :: interprocess, хотя и посмотреть, как они работают с разделяемой памятью и т. д. на Linux/POSIX - теперь она была тщательно протестирована, поэтому их методы должны быть довольно надежными. –

ответ

1

But it seems to me ridiculous that I have to add 'volatile' to all the functions in the libraries that are not necessarily mine.

Вот что с ++ говорит стандарт он должен сделайте. Вы можете отбросить спецификатор const/volatile, но, делая это, вы можете ввести UB.

Or can I access shared memory data without using volatile in first place?

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

Вам понадобится летучесть в случае, когда ваша FPGA записывает в некоторую память (которая не является общей памятью).

+0

Некоторые из моих данных однонаправлены. То есть Process1 только записывает член данных в местоположение в общей памяти, тогда как Process2 только считывает одно и то же местоположение. Насколько я понимаю (без особой уверенности), операции чтения в Process2 могут быть удалены компилятором. И именно там volatile обеспечивает правильные операции чтения. Я ошибаюсь? Вы все еще говорите, что доступ к общей памяти без волатильности гарантирует правильную работу? – user22097

+0

@ user22097 Вы ошибаетесь. Доступ к общей памяти отлично работает без волатильности. Однако, если вы хотите, чтобы один процесс ждал, пока кто-то закончит писать, лучше создать семафор. –

+0

Приятно знать, что я был неправ. Но мне интересно, в чем разница между общей памятью, не требующей волатильности и других типов памяти, которая требует волатильности. Не могли бы вы дать мне некоторое объяснение, ссылку или ключевые слова, чтобы я мог больше учиться? Благодарю. – user22097