Gleichzeitige Thread-Zugriffe auf einen Speicherbereich verhindern

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu So erstellen Sie Multithread-Anwendungen

Mit Hilfe der folgenden grundlegenden Techniken können Sie verhindern, dass andere Threads auf denselben Speicherbereich wie Ihr Thread zugreifen:

So sperren Sie Objekte:

  1. Bei Objekten wie z.B. Canvas, die über die Methode Lock verfügen, rufen Sie je nach Bedarf die Methode Lock auf, um einen Zugriff anderer Objekte auf das Objekt zu verhindern, und Sie rufen die Methode Unlock auf, wenn das Objekt nicht mehr geschützt zu werden braucht.
  2. Rufen Sie TThreadList.LockList (Delphi) oder TThreadList::LockList() (C++) auf, um Threads an der Verwendung des Listenobjekts TThreadList zu hindern. Wenn die Sperre nicht mehr erforderlich ist, rufen Sie TThreadList.UnlockList auf.

Hinweis: Aufrufe von TCanvas.Lock und TThreadList.LockList sind immer sicher.

So verwenden Sie einen kritischen Abschnitt:

  1. Erstellen Sie eine globale Instanz des Objekts TCriticalSection.
  2. Rufen Sie die Methode Acquire auf, um beim Zugriff auf den globalen Speicher anderen Threads den Zugriff zu verweigern.
  3. Rufen Sie die Methode Release auf, damit andere Threads über einen Aufruf der Methode Acquire auf den Speicher zugreifen können.Im folgenden Quelltext wird eine globale Variable namens LockXY verwendet, die einen kritischen Abschnitt repräsentiert und den Zugriff auf die globalen Variablen X und Y blockiert. Um X oder Y benutzen zu können, müssen Threads die entsprechenden Anweisungen, wie im Folgenden gezeigt, mit Aufrufen der betreffenden Methoden des kritischen Abschnitts umgeben:

Delphi:

LockXY.Acquire;
try
  X := X + 1;
  Y := sin(X);
finally
  LockXY.Release
end;

C++:

LockXY->Acquire();
try
{
  x++;
  y = sin( x );
}
__finally
{
  LockXY->Release();
}

Warnung: Kritische Abschnitte haben nur dann den gewünschten Effekt, wenn alle Threads kritische Abschnitte für den Zugriff auf den globalen Speicher benutzen. Andernfalls sind gleichzeitige Zugriffe möglich.

So verwenden Sie eine Synchronisierungsfunktion, die mehrere Leseoperationen, aber nur eine exklusive Schreiboperation zulässt:

  1. Erstellen Sie eine globale Instanz des Objekts TMultiReadExclusiveWriteSynchronizer, die dem globalen Speicher zugeordnet ist, der geschützt werden soll.
  2. Bevor ein Thread Daten aus dem Speicher lesen kann, muss er BeginRead aufrufen.
  3. Bei Beendigung des Lesevorgangs muss der Thread EndRead aufrufen.
  4. Bevor ein Thread Daten in den Speicher schreiben kann, muss er BeginWrite aufrufen.
  5. Bei Beendigung des Schreibvorgangs muss der Thread EndWrite aufrufen.

Warnung: Die Synchronisierungsfunktion hat nur dann den gewünschte Effekt, wenn jeder Thread sie zum Zugriff auf den zugehörigen globalen Speicher verwendet. Andernfalls sind gleichzeitige Zugriffe möglich.

Siehe auch