2009-06-19 9 views
1

Ich habe eine Funktion, die der Hauptengpass meiner Anwendung ist, weil sie schwere String-Vergleiche mit einer globalen Liste unter den Threads macht. Meine Frage ist grundlegend das:Mehrfachverriegelung in der gleichen Funktion

Ist es praktisch, die Liste (genannt List gList) mehrmals in 1 Funktion zu sperren. Um sie dann später wieder zu sperren (Einfaches Sperren während des Nachschlagens, Entsperren, um ein neues Element zum Einfügen bereit zu machen, dann erneut sperren und das neue Element hinzufügen).

Wenn ich Sie ein Profiler sehe ich keine Anzeichen dafür, dass ich einen hohen Preis dafür bezahlen, aber könnte ich zu einem späteren Zeitpunkt oder wenn der Code es in freier Wildbahn sein? Hat jemand hier Best Practice oder persönliche Erfahrung?

+0

ändern und entfernen Sie auch Elemente aus dieser Liste? – BlackTigerX

Antwort

1

Es klingt wie Sie wollen nicht die Sperre zwischen der Suche und dem Einsetzen zu veröffentlichen. Entweder das, oder Sie müssen während der Suche überhaupt nicht sperren.

Möchten Sie der Liste nur hinzufügen, wenn das Element noch nicht vorhanden ist? Wenn dies der Fall ist, kann durch das Aufheben der Sperre zwischen den beiden Schritten ein weiterer Thread zur Liste hinzugefügt werden, während Sie Ihr Element vorbereiten. Wenn Sie zum Hinzufügen bereit sind, ist Ihre Suche veraltet.

Wenn es sich bei dem Suchvorgang nicht um ein Problem handelt, das veraltet sein kann, müssen Sie während des Suchvorgangs wahrscheinlich nicht gesperrt werden.

1

Im Allgemeinen möchten Sie für so kurze Zeit wie möglich sperren. Die Kosten einer Contention sind viel höher (müssen zum Kernel gehen) als die Kosten einer konfliktfreien Lock Acquisition (kann im Userspace getan werden), so dass eine feinkörnigere Lockerung normalerweise gut für die Performance ist, selbst wenn es bedeutet, die mehrmals sperren.

Das heißt, stellen Sie sicher, dass Sie in einer geeigneten Situation für dieses Profil: eine mit einer hohen Menge an gleichzeitiger Belastung. Sonst haben Ihre Ergebnisse wenig Bezug zur Realität.

1

Meiner Meinung nach gibt es zu wenige Daten, um eine konkrete Antwort zu geben. Im Allgemeinen verursacht die Anzahl der Sperren kein Leistungsproblem, sondern die Anzahl der Threads, die auf diese Sperre warten.

5

Wie führen Sie die Verriegelung durch? Vielleicht möchten Sie in die Verwendung von ReaderWriterLockSlim schauen, wenn das nicht schon der Fall ist.

Hier ist ein einfaches Anwendungsbeispiel:

class SomeData 
{ 
    private IList<string> _someStrings = new List<string>(); 
    private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); 

    public void Add(string text) 
    { 
     _lock.EnterWriteLock();    
     try 
     { 
      _someStrings.Add(text); 
     } 
     finally 
     { 
      _lock.ExitWriteLock(); 
     } 

    } 

    public bool Contains(string text) 
    { 
     _lock.EnterReadLock(); 
     try 
     { 
      return _someStrings.Contains(text); 
     } 
     finally 
     { 
      _lock.ExitReadLock(); 
     } 
    } 
} 
+0

Sperren Sie es nur für Lesezugriff, es sei denn, Sie ändern die Liste tatsächlich – jjxtra

Verwandte Themen