Синхронизация IPC с общей памятью (без блокировки)
Рассмотрим следующий сценарий:
Требования:
Сервер Intel x64 (несколько процессорных сокетов => NUMA)Ubuntu 12, GCC 4.6Два процесса, совместно использующие большие объемы данных в (именованной) разделяемой памятиКлассический сценарий производитель-потребительПамять расположена в круговом буфере (с М элементами)Программная последовательность (псевдокод):
Процесс А (Производитель):
int bufferPos = 0;
while( true )
{
if( isBufferEmpty( bufferPos ) )
{
writeData( bufferPos );
setBufferFull( bufferPos );
bufferPos = ( bufferPos + 1 ) % M;
}
}
Процесс Б (Потребитель):
int bufferPos = 0;
while( true )
{
if( isBufferFull( bufferPos ) )
{
readData( bufferPos );
setBufferEmpty( bufferPos );
bufferPos = ( bufferPos + 1 ) % M;
}
}
Теперь извечный вопрос: как их эффективно синхронизировать !?
Защитите каждый доступ на чтение / запись с помощью мьютексовВведите «льготный период», чтобы разрешить запись для завершения: чтение данных в буфере N, когда буфер (N + 3) помечен как заполненный (опасно, но, кажется, работает ...)?!?В идеале я хотел бы что-то вроде барьера памяти, который гарантирует, что все предыдущие чтения / записи видны на всех процессорах, в соответствии с:
writeData( i );
MemoryBarrier();
//All data written and visible, set flag
setBufferFull( i );
Таким образом, мне нужно было только отслеживать флаги буфера, а затем безопасно читать большие порции данных.
Обычно я ищу что-то вроде ограждений для получения / выпуска, как описано здесь Preshing:
http://preshing.com/20130922/acquire-and-release-fences/
(Если я правильно понимаю, атомарность C ++ 11 работает только для потоков одного процесса, а не для нескольких процессов.)
Однако собственные барьеры памяти GCC (__sync_synchronize в сочетании с барьером компилятора asm volatile ("" ::: "memory"), безусловно, не работают должным образом, поскольку записи становятся видимыми после барьера, когда я ожидал, что они будут завершены.
Любая помощь будет оценена ...
Кстати: под окнами это просто отлично работает, используя переменные переменные (специфическое поведение Microsoft) ...