Bei der Implementierung eines kleinen Projekts mit der CMSIS RTOS Implementierung RTX (http://www.keil.com/pack/doc/CMSIS/RTOS/html/_function_overview.html) habe ich folgendes Problem: Die betroffenen Threads sollen immer nur dann aktiv werden, wenn sich eine von einer Hand voll Variablen ändert. Dabei sind die Variablen sowohl von verschiedenen Threads änderbar als auch Abhängigkeiten anderer Threads (also wo auf Änderung dieser gewartet wird). Um nicht zu beeinflussen, nenne ich erstmal nicht die Lösung, die ich aktuell nur sehe. Meine Frage ist nun also, was für ein Design Pattern Ihr im gegebenen Problem verwenden würdet. Danke!
guest schrieb: > Mutexes Und wie soll das genau funktionieren? Derjenige, der den schreibt, muss den dann ja entsprechend releasen, wenn was neues reingeschrieben wurde. Aber wie soll er den wieder bekommen? Und wie soll das funktionieren, wenn mehrere die Variablen schreiben können?
jeder Task, der in die Variable benutzen möchte (lesend oder schreibend) fordert den Mutex vom OS an. Meistens so (pseudocode): if(OS_MutexPend(&mutex, TIMEOUT_TIME)) { // Tu was mit der Variable OS_MutexRelease(&mutex); } OS_MutexPend wartet dabei so lange, bis die Mutex frei geworden oder die Timeoutzeit abgelaufen ist. Bekommt der Task die Mutex nicht, dann muss er es beim nächsten Durchlauf noch einmal probieren.
Horst schrieb: > Die betroffenen Threads sollen immer nur dann aktiv werden, wenn sich > eine von einer Hand voll Variablen ändert. Dabei sind die Variablen > sowohl von verschiedenen Threads änderbar als auch Abhängigkeiten > anderer Threads (also wo auf Änderung dieser gewartet wird). Um race conditions beim Ändern der Variablen zu verhindern (ein thread sieht die Variablen in einem noch nicht korrekt aktualisiertem Zustand), verwendest Du einen mutex. Um einem anderen thread die gewünschte Zustandsänderung anzuzeigen, nutzt Du, was immer Dir Dein OS zu verfügung stellt. Ein kurzer Blick auf die Doku Deines OS lässt vermuten, dass ein thread in der Regel in osWait() hängen sollte und laut Dokumentation da wieder raus kommt, wenn Du ihm ein "Signal, Message oder Mail" schickst. mfg Torsten
:
Bearbeitet durch User
Ich würde das etwa so machen. ...ist zwar Pseudocode, müsste aber je nach OS irgendwelche Möglichkeiten geben, das so ähnlich umzusetzen. //Thread while(runnning) { switch (WaitMultiEvent(&modifyEvent, &terminateEvent) ) { case 0: //Signal, dass Variablen modifiziert wurden GetLock(&rwLock) //Variablen manipulieren ReleaseLock(&rwLock); break; case 1: //Thread soll beenden runnning = false; break; } if ( running == false ) { //Resourcen freigeben } }
Torsten R. schrieb: > Ein kurzer Blick auf die Doku Deines OS lässt > vermuten, dass ein thread in der Regel in osWait() hängen sollte und > laut Dokumentation da wieder raus kommt, wenn Du ihm ein "Signal, > Message oder Mail" schickst. Ich persönlich scheitere hier immer daran, dass beim Keil OS die Signale den Threads gehören. Wenn ein Thread eine bestimmte Variable verändert, will ich ihm aber nicht die zusätzliche Information geben, welche anderen Threads daraufhin geweckt werden sollen. Ich möchte lieber die relevanten Threads auf das Ereignis warten lassen. Ich verstehe die Fragestellung des TO in ähnlicher Weise und verfolge gespannt die weitere Diskussion.
Steffen R. schrieb: > Torsten R. schrieb: >> Ein kurzer Blick auf die Doku Deines OS lässt >> vermuten, dass ein thread in der Regel in osWait() hängen sollte und >> laut Dokumentation da wieder raus kommt, wenn Du ihm ein "Signal, >> Message oder Mail" schickst. > > Ich persönlich scheitere hier immer daran, dass beim Keil OS die Signale > den Threads gehören. Wenn ein Thread eine bestimmte Variable verändert, > will ich ihm aber nicht die zusätzliche Information geben, welche > anderen Threads daraufhin geweckt werden sollen. > > Ich möchte lieber die relevanten Threads auf das Ereignis warten lassen. > > Ich verstehe die Fragestellung des TO in ähnlicher Weise und verfolge > gespannt die weitere Diskussion. Ja, posix condition variables machen in etwa genau das (sie sind dem erwarteten Zustand zugeordnet). Na, dann müsste man eine Liste implementieren, in die sich die threads, die sich für ein Ereignis/Zustand interessieren eintragen.
guest schrieb: > jeder Task, der in die Variable benutzen möchte (lesend oder > schreibend) > fordert den Mutex vom OS an. > > Meistens so (pseudocode): > > if(OS_MutexPend(&mutex, TIMEOUT_TIME)) > { > > // Tu was mit der Variable > > OS_MutexRelease(&mutex); > } > > OS_MutexPend wartet dabei so lange, bis die Mutex frei geworden oder die > Timeoutzeit abgelaufen ist. > > Bekommt der Task die Mutex nicht, dann muss er es beim nächsten > Durchlauf noch einmal probieren. Das ist mir schon klar, wozu ein Mutex da ist. Aber wie ich das geschickt zwischen mehreren Lesern und Schreibern verwende sehe ich noch nicht... Torsten R. schrieb: > Ein kurzer Blick auf die Doku Deines OS lässt > vermuten, dass ein thread in der Regel in osWait() hängen sollte und > laut Dokumentation da wieder raus kommt, wenn Du ihm ein "Signal, > Message oder Mail" schickst. Normal kann man, wie ich das bisher gesehen habe, in RTX immer nur auf eine Message warten. Also im Kernel muss ja registriert werden, dass der Thread auf MessageQueue X wartet und wüsste ich nicht, wie man da sagen kann warte auf X oder Y. (der entsprechende Aufruf lautet osMessageGet(MsgBox, osWaitForever);) Wenn ich nur osWait aufrufe weiß ja niemand, dass der Thread auf MessageQueue Y wartet. Guido schrieb: > WaitMultiEvent Siehe oben, man kann meines Wissens irgendwie nur auf ein Event warten, keine Veroderung. Steffen R. schrieb: > Ich persönlich scheitere hier immer daran, dass beim Keil OS die Signale > den Threads gehören. Wenn ein Thread eine bestimmte Variable verändert, > will ich ihm aber nicht die zusätzliche Information geben, welche > anderen Threads daraufhin geweckt werden sollen. > > Ich möchte lieber die relevanten Threads auf das Ereignis warten lassen. > > Ich verstehe die Fragestellung des TO in ähnlicher Weise und verfolge > gespannt die weitere Diskussion. Exakt. Man müsste eben eine Verwaltung selbst machen, in der drin steht, welche Threads sich für Variable X interessieren. Bei dieser könnten sich dann Threads anmelden und sagen, sie wollen in Zukunft darüber benachrichtigt werden. Die andere Möglichkeit wäre so eine Art MessageBus, wo dann jeder Thread selbst schauen kann, welche Nachricht er verwerten möchte. Das würde natürlich gewissen Overhead mitbringen und möglicherweise Probleme bei der Speicherverwaltung. Torsten R. schrieb: > Ja, posix condition variables machen in etwa genau das (sie sind dem > erwarteten Zustand zugeordnet). > > Na, dann müsste man eine Liste implementieren, in die sich die threads, > die sich für ein Ereignis/Zustand interessieren eintragen. Danke, ersteres werde ich mir mal anschauen. Und ja, die Liste wäre auch meine Idee gewesen, aber ich habe gehofft, dass es noch was einfacheres gibt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.