Synchronisieren von Methoden
-
Hallo,
ich habe eine Klasseninstanz "theObject" die zwei Methoden enthält, welche ein Objekt neu zeichnen. Die Klasse wird global über "extern" verwendet. Die Methoden heissen: "MoveObject" und "DrawObject". Sie funktionieren unterschiedlich, verwenden aber teilweise gleichen CodeDer Thread kann Pausiert werden:
while(1) { sleep(uCounter); if(!bProcessThread) continue; doSomeThing(); theObject->MoveObject(); }Außerdem gibt es eine "Initialize" Methode im Thread. Diese kann unterschiedliche Daten erhalten. Was wichtig ist: "Initialize" ruft "theObject->DrawObject" auf. Außerdem kann über die Hauptanwendung "theObject->DrawObject" aufgerufen werden.
Wenn nun in der Schleife "theObject->MoveObject();" aufgerufen werden soll und
theObject->DrawObject aktiv ist, so soll solange gewartet werden, bis theObject->DrawObject durchgeführt wurde und erst dann theObject->MoveObject() laufen.Wie kann man am besten sicherstellen, dass sich die beiden Methoden nicht gegenseitig behindern?
-
Ich würde ja ein Semaphor oder eine Critical Section anlegen und die Funktionen blockieren (oder abbrechen) lassen, wenn sie ausgesperrt wurden.
(btw, von der Namensgebung her sollte sich MoveObject() nicht um's Zeichnen kümmern - sondern bestenfalls die Positionsangaben für den nächsten Zeichnen-Durchlauf anpassen)
-
Da hab ich gleich auch mal eine Frage zu:
wie kann ich eine Crtitical_section, in einer C-Datei für alle Methoden zugänglich machen, ohne da immer den Pointer auf die CS hin und her schmeißen zu müssen.
geht das mit:static Critical_Section cs? oder ist Critical_section als solches Static?
Ich beziehe mich auf eine static Libary(.a), die keine Main-Methode hat.
Und kann man einer Libary einen Thread starten, oder benötigt man dafür eine DLL bei Windows?
-
In C++ (jetzt basierend auf frager's Problem) würde ich dem Objekt die CS als Member übergeben - da kommen alle seine Methoden dran. Unter C mußt du die CS überall mitschleifen, wo sie gebraucht wird.
(und ja, auch aus einem DLL-freien Programm kannst du Threads erzeugen ;))
-
Mist ist C. Aber, gut das es mit den Threads geht, dann bin da schon mal auf dem richtigen Weg. Jetzt noch eine Frage zu meiner Critical_Section:
Nur noch mal für blöde,ich habe eine c-Datei, nen wir sie io.c, in der schreibe ich
Critical_Section csdann müsste ich doch in io.c alle Methoden die enthalten sind mit enter/leave schützen können, oder ?
ich brauche keine geschützten Bereiche außerhalb von io.c
Gruß ein auf-der-Leitung-steher
-
Ja, so sieht es aus - aber ob die Funktionen das machen, ist dann ihre Sache. Dazu muß jede Funktion die wichtigen Teile ihrer Arbeit in einen EnterCriticalSection() ... LeaveCriticalSection() einschließen, sonst nutzt die CS überhaupt nichts.
-
alles klar, danke erstmal.

-
Hallo mal wieder.
Ich hatte folgenden Code von einem Bekannten bekommen..Im thread:
while(1) { sleep(uCounter); if(!bProcessThread) continue; doSomeThing(); while(pReplayView->IsDrawing()) {} // Warten theObject->SetReadyForDrawing(false); // Blockieren für DrawObject theObject->MoveObject(); theObject->SetReadyForDrawing(true); // Freigeben }In der Methode DrawObject
while(!m_bReadyForDrawing) {} // Warten m_bDrawing = true; // Code der das Zeichnen durchführt u.a m_bDrawing = false;Und SetReadyForDrawing(bool bReady)
m_bReadyForDrawing = bReady;IsDrawing ()
return m_bDrawing;In MoveObject kann der Code normal durchlaufen, ohne Überprüfung
Das klappte bei der Debug Version, nicht jedoch beim Release. Daher hatte ich einiges anderes ausprobiert
Jetzt habe ich habe herausgefunden, dass wenn man m_bDrawing und m_bReadyForDrawing volatile macht auch die Release Version funktioniert.
Schön ist die Lösung ja nicht unbedingt. Die while-Schleifen gefallen mir nicht so...
-
Das dürfte mit der Optimierung zusammenhängen - nicht-volatile Variablen könnten im Register verpackt werden und dann merken die Threads nichts mehr davon, daß ihre Vorbedingungen geändert wurden.
Aber der Ansatz über solche Test-Variablen ist sowieso unsicher, weil du nicht kontrollieren kannst, welcher Thread wann den Prozessor bekommt. Deshalb gibt es echte Synchonisationsmechanismen wie Events oder Critical Sections. (die Begriffe solltest du mal an Google weiterleiten, da findet sich bestimmt was hilfreiches)