2012-04-13 5 views
5

int val = memLoc[index++];Kann ich den folgenden Code lock free/atomic machen?

oder besser noch

int val = memLoc[index++ & 0xFF];

Der Versuch, eine THREAD aus einem gemeinsamen Ringpuffer gelesen zu tun, wo jeder Anruf den nächsten Wert bekommt - und ich würde es lieben Sperre frei zu sein, wenn bei alles möglich, wie es ein TON passiert. No Boost/C++ 11 erlaubt :(

+3

Sie könnten daran interessiert sein, [diesen Artikel] (http://www.codeproject.com/Articles/43510/Lock-Free-Single-Producer-Single-Consumer-Circular) zu lesen. –

+3

Nein C++ 11 bedeutet, dass Sie eine Vor-Standard-Lösung benötigen. Wenn Boost inakzeptabel ist, sind vermutlich alle anderen Bibliotheken (mit ihren strengeren Lizenzbedingungen) ebenfalls aus, so dass Sie nichts Portables bekommen können. Also, auf welchem ​​Betriebssystem brauchst du das? – MSalters

+0

Welcher Typ ist 'memLoc'? Ist es ein Zeiger (oder Array) in "int"? –

Antwort

6

Die einzige Operation, die hier synchronisiert werden muss, ist das Inkrement des index Wertes. Da dies nur ein numerischer Wert ist, kann es ohne die Verwendung von Sperren über ein atomares Inkrement erfolgen. der Rest der Operationen, die Sie aufgelistet sind nur von einem gemeinsamen Standort liest und müssen nicht synchronisiert werden.

auf Win32 den Zuwachs macht synchronisiert ist

mit der InterlockedIncrement Funktion getan
int oldValue = InterlockedIncrement(&index); 
int val = memLoc[oldValue & 0xFF]; 

Es gibt verschiedene Synchronized Inkrementieren Sie Funktionen, die auf Linux verfügbar sind d Diskussion über die Optionen auf dieser Stackoverflow Thread

+2

In C++ 11 gibt es 'std :: atomic_fetch_add ', was den Trick machen sollte. –

+0

Gibt es Architekturen, bei denen das Schreiben eines 'int' nicht atomar wäre (wo müssten Sie das gelesene Element synchronisieren)? –

+0

@MarkB das Problem ist nicht nur das atomare Schreiben des Elements, es ist das atomare Schreiben + Lesen des alten Wertes + sicherzustellen, dass es über alle Prozessoren gesehen wird. Normalerweise benötigen Sie dafür eine spezielle Anweisung. Mit Blick auf meine Antwort habe ich an einigen Stellen Atomwaffen missbraucht. Ich werde das aufräumen. – JaredPar

1

Sie benötigen würde zu erhöhen und Index in einer atomaren Operation zurückgelesen. Leider garantiert der Operator ++ keine Atomizität.

Die meisten Prozessoren haben eine Art Fetch-Increment-Store-Anweisung, die verwendet werden kann. Sie können dazu eine Inline-Assembly einfügen. http://en.wikipedia.org/wiki/Fetch-and-add

Wenn Sie unter Windows laufen lassen, bietet MS eine API diese zuzugreifen: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684122(v=vs.85).aspx

Wenn Sie auf einem anderen Betriebssystem sind, gibt es wahrscheinlich eine ähnliche Funktionalität. In jedem Fall benötigen Sie jedoch einen OS- oder niedrigeren Zugriff, um einen Atom-Fetch-Inkrement-Speicher zu erhalten.

Verwandte Themen