Threads: gemeinsam genutzter Speicher möglich?



  • Ich schreibe an einer Anwendung bei der zum einen sichergestellt werden muss, dass bestimmte (Hardware-)Zugriffe periodisch asgeführt werden, zum anderen muss aber auch mit einem Netzwerk-Server komnuniziert werden.

    Als lösung fällt mir spontan die Verwendung von mehreren Threads ein, die jeweils eine Aufgabe "erledigen".

    Jedoch benötige ich von allen Seiten den Zugriff auf die eigentlichen Daten der Anwedung - welche im konkreten Fall in einer Verketteten Liste abgelegt sind.

    Nun stelle ich mir die Farg, ob ein Zugriff auf eine (sich evtl. verändernde) verkettete Liste aus mehreren Therads möglich bzw. überhaupt zulässig ist.

    Hat hier jemand Erfahrungen?
    Wie wird sowas gelöst?



  • Hallo

    Eine einfache List muß synchroniziert werden, in der Regel mittels einer TCriticalSection.

    bis bald
    akari



  • Ok, nun betrete ich absolutes Neuland. Also das mit Thereads werde ich hinbekommen, aber gibt es irgendwo ein verständliches Beispiel für die Verwendung von TCriticalSection?



  • Hallo

    Siehe BCB-Hilfe zu TCriticalSection. Zum Beispiel den Artikel "TCriticalSection verwenden"

    bis bald
    akari



  • Naja die Hilfe ist eigentlich eine erklärung der Funktionsnahmen. Irgendwie kann ich mir damit nicht vorstellen wie ich das ganze einsetzen soll.

    Kennt jemand ein Besipiel?



  • Hallo

    Selbstverständlich ist in der Builder-Hilfe auch ein Beispiel für den Einsatz von TCriticalSection, in dem vom mir genannten Artikel. 🙄

    pLockXY->Acquire(); // Andere Threads aussperren
    
    try
    {
      Y = sin(X); // Payload
    }
    __finally
    {
      pLockXY->Release();
    }
    

    pLockXY ist vom Typ TCriticalSection und sollte so deklariert und verwaltet sein das eine Instanz für alle Threads zuständig ist (also nicht lokal).
    Die Zeile mit Payload ist der Teil des Programms der zwischen den Threads synchronisiert werden soll.

    bis bald
    akari



  • Am besten kapselt man ein TCriticalSection in eine Guard Klasse, damit das Verlassen der Critical Section immer gewährleistet wird. Akaris Vorschlag funktioniert zwar, ist aber unschön wenn die aufgetretene Exception erneut geworfen werden soll.

    class TLock
    {
       TCriticalSection *CriticalSection;
    public:
       TLock( TCriticalSection& Sect ) : CriticalSection( &Sect )
       {
          // Critical Section betreten
          CriticalSection->Acquire();
       }
    
       ~TLock()
       {
          // Critical Section verlassen
          CriticalSection->Release();
       }
    };
    
    class SyncAccess
    {
       TCriticalSection*      CritSect;
    
    public:
       SyncAccess()
       {
          CritSect = new TCriticalSection();
       }
    
       ~SyncAccess()
       {
          delete CritSec;
       }
    
       void sync_access()
       {
          // Critical Section wird beim Erzeugen des lock Objektes Betreten
          TLock lock( *CritSect );
    
          // do some stuff
    
          // Critical Section wird beim Verlassen der Funktion Verlassen, da das
          // lock Objekt out-of-scope geht und der Destruktor die Critical Section
          // verlässt.
       }
    };
    

    Gruß,
    Doc


Anmelden zum Antworten