Threadsicherheit --> Absichern von Funktionen



  • Hi,

    ich glaube ich habe mich da ein wenig verschusselt beim Multithreading.

    Greife ich von Threads auf Variablen zu oder auf Variablen in Threads, so benutze ich Synch Objekte. Soweit ok.

    Nun habe ich mir allerdings ein Konstrukt zurechtgefusselt, das mir Probleme bereitet.

    Abstrakt:

    Ich habe ein Formular laufen. In diesem Formular gibt es ein Objekt einer Klasse M.
    In dieser Klasse werden drei TThreads erzeugt. TA , TB und TC. Weiterhin existiert in dieser Klasse ein weiteres Objekt einer Interface Klasse I. I beinhaltet simple Funktionen, die weiterverteilen.

    Sagen wir mal es existiert eine Funktion Spread_Intern. Diese Funktion bekommt das Handle des Senders als Parameter und eine Nachricht MSG (unsigned int).
    Anhand von IF Anweisungen verteilt diese Funktion nun etwas an einen Empfänger anhand der Nachricht und des Senders.

    Codeschnipsel:

    void Interfac::Spread_Intern(unsigned int message, unsigned int sender)
    {
    //Befehle von TA
       if (sender==controller->Handle) {
    		//an TB
    		if (message==MSG_OPEN) {
    			PostThreadMessage(door->ThreadID, MSG_OPEN,0,0);
    		}
    		if (message==MSG_CLOSE) {
    			PostThreadMessage(door->ThreadID, MSG_CLOSE,0,0);
    		}
    		if (message==MSG_DRIVING) {
    			door->elev_arrived->Acquire();
    			door->elev_arrived->ResetEvent();
    			door->elev_arrived->Release();
    		}
    		if (message==MSG_ARRIVED) {
    			door->elev_arrived->Acquire();
    			door->elev_arrived->SetEvent();
    			door->elev_arrived->Release();
    		}
    
       }
       //Befehle von TC
       if (sender==doorsim->Handle) {
                    //an TB
    		if (message==MSG_OPENED) {
    			PostThreadMessage(door->ThreadID, MSG_OPENED,0,0);
    		}
    		if (message==MSG_CLOSED) {
    			PostThreadMessage(door->ThreadID, MSG_CLOSED,0,0);
    		}
       }
    

    So geht das also in der Funktion fröhlich weiter. TB an TA, TA an TB, TC an TA etc blabla. Alles in der Art.

    IN den Threads sehen die Aufrufe dann so aus:

    interf->Spread_Intern(MSG_OPENED,this->Handle);
    

    interf ist ein Objekt der Inferface Klasse. interf existiert in jedem Thread durch forward declaration. Die Adresse von interf wird über den Konstruktor mitgegeben. Die Threads und interf liegen alle in M.

    Das Interface kommuniziert über ähnliche Funktionen auch mit dem Formular. Sämtliche Kommunikation wird also über Memberfunktionen der Interface Klasse geroutet. Der Grund hierfür ist eine Parametrierung über Ini Dateien.

    Nun meine Frage. Bisher dachte ich, da das nur Funktionen sind und die eigentlichen Objektänderungen über Acquire und Release im entsprechenden Thread abgesichert sind, bzw. PostMessage das nicht benötigt, daß das keine Probleme gibt.

    Nun bin ich mir allerdings nicht ganz sicher. Müsste ich die Aufrufe der spread_intern Funktion auch mit Synch Objekten absichern? Gibt das auf die Art wie es jetzt ist doch Probleme, wenn da zwei Threads gleichzeitig durch die Funktion flitzen?

    Wie gesagt sind in dieser Interface Klasse keinerlei Variablen, die verändert werden. Sie routet nur zwischen den Threads hin und her.

    Nur können ja auch zwei Threads gleichzeitig die Funktion mit utnerschiedlichen Parametern aufrufen... Kommen die sich dann ins Gehege?



  • schlimmstenfalls gibts ja Mutexe 🙂 Würd ich grundsätzlich nutzen, wenn ich auf irgendwelche Ressourcen zugreife..



  • Die Spread_Intern Funktion selbst wird sich wohl nicht stören wenn sie in mehreren Threads läuft - zumindest sieht das was du hier an Code gepostet hast OK aus.

    Die Frage ist... wird "controller" jemals geändert oder ist es "invariant"? Wird "controller->Handle" jemals gändert? Wird "door", "door->elev_arrived" oder "door->ThreadID" jemals geändert? Wenn ja hast du vermutlich ein Problem 😉

    Und nochwas: unterschiedliche Parameter machen garnix, da jeder Thread seine eigene Kopie der Parameter sieht, genauso von lokalen Variablen und temporaries.


Anmelden zum Antworten