Shared-memory IPC-Synchronisation (lock-frei)

Betrachten Sie das folgende Szenario:

Anforderungen:

  • Intel x64 Server (mehrere CPU-sockel => NUMA)
  • Ubuntu 12, GCC 4.6
  • Zwei Prozesse, welche große Mengen von Daten über (benannte) shared-memory -
  • Klassischen Erzeuger-Verbraucher-Szenario
  • Speicher angeordnet ist, in einen Ringspeicher (mit M Elementen)

Programm-Sequenz (pseudo-code):

Prozess Ein (Hersteller):

int bufferPos = 0;
while( true )
{
    if( isBufferEmpty( bufferPos ) )
    {
        writeData( bufferPos );
        setBufferFull( bufferPos );

        bufferPos = ( bufferPos + 1 ) % M;
    }
}

Prozess B (Verbraucher):

int bufferPos = 0;
while( true )
{
    if( isBufferFull( bufferPos ) )
    {
        readData( bufferPos );
        setBufferEmpty( bufferPos );

        bufferPos = ( bufferPos + 1 ) % M;
    }
}

Nun die uralte Frage: Wie synchronisieren Sie Sie effektiv!?

  1. Schützen jeder lese - /schreib-Zugriff mit Mutexe
  2. Die Einführung einer "Karenzzeit", um zu erlauben, schreibt abschließen: Lesen der Daten im Puffer N, wenn Puffer(N+3) markiert wurde, wie die volle (gefährlich, aber scheint zu funktionieren...)
  3. ?!?

Idealerweise würde ich gerne etwas entlang der Linien von einer memory-Barriere, die gewährleistet, dass alle vorherigen liest/schreibt, sind sichtbar über alle CPUs, entlang der Linien von:

writeData( i );
MemoryBarrier();

//All data written and visible, set flag
setBufferFull( i );

So, ich würde nur beobachten, wie sich die buffer-flags und dann Lesen konnte, die große Daten-chunks sicher.

Generell bin ich auf der Suche nach etwas entlang der Linien von " acquire/release Zäune, wie beschrieben, durch Preshing hier:

http://preshing.com/20130922/acquire-and-release-fences/

(wenn ich es richtig verstehe, die C++11 atomics funktionieren nur für die threads eines einzelnen Prozesses und nicht über mehrere Prozesse.)

Jedoch die GCC-eigenen memory-Barrieren (__sync_synchronize in Kombination mit den compiler-Barriere asm volatile( "" ::: "memory" ), um sicher zu sein) scheinen nicht wie erwartet funktionieren, so schreibt sichtbar werden, nachdem die Barriere, wenn ich erwartet, dass Sie abgeschlossen sein.

Jede Hilfe würde geschätzt...

BTW: Unter windows-das funktioniert gut mit volatile-Variablen (eine Microsoft-spezifische Verhalten)...

InformationsquelleAutor Ben | 2014-03-05
Schreibe einen Kommentar