Ich habe eine Windows Applikation, die mehrere Threads startet. Aus einem hier nicht näher beschriebenen Grund muss ich jetzt dafür sorgen, das diese Threads nicht gleichzeitig ausgeführt werden. Ich habe mit SetThreadGroupAffinity() versucht alle Threads auf dem ersten Core laufen zu lassen aber wahrscheinlich durch Hyperthreading werden immer noch Threads gleichzeitig ausgeführt. Gibt es mit Hilfe der Windows API eine Möglichkeit zu verhindern, das Threads gleichzeitig ausgeführt werden? Ich weiß, das ist nicht der übliche Use-Case, weil man ja eigentlich genau das will. Ein Locken durch Mutex/Semaphore kann ich leider auch nicht machen, weil es Threads gibt, die zu einem beliebigen Zeitpunkt einen anderen Thread unterbrechen können müssen.
Stichwort ist "Semaphoren". Aber Vorsicht, der Deadlock ist ein vielfältiger und hinterlistiger Gegner :-)
Tom schrieb: > Ein Locken > durch Mutex/Semaphore kann ich leider auch nicht machen, weil es Threads > gibt, die zu einem beliebigen Zeitpunkt einen anderen Thread > unterbrechen können müssen. Eben erst gelesen, sorry aber was soll das? Du willst duschen ohne nass zu werden? Wenn du nicht willst daß mehr als ein Thread läuft, dann können auch andere Threads dann nicht zu beliebiger Zeit andere unterbrechen. Ich würde mal sagen: Du hast kein funktionierendes Konzept für dein Problem, oder es gibt kein Konzept.
Der Andere schrieb: > Ich würde mal sagen: Du hast kein funktionierendes Konzept für dein > Problem, oder es gibt kein Konzept. Doch, das habe ich und ja ich weiß, das die Anforderungen pervers klingen und auf dem ersten Blick keinen Sinn ergeben. Aber wie oben geschrieben, möchte ich hier auf die eigentliche Applikation nicht weiter eingehen.
Kurze antwort: wenn du deine merkwürdige app nicht ändern kannst...geht nicht ohne einen eigenen windows kernel. Kurzgesagt was du vorhast macht keinen sinn und ist übelster schwachsinn...freitag halt
Definiere "Gleichzeitig". Gleichzeitig im Sinne von "auf mehreren Kernen parallel laufen" oder im Sinne von "im präemptiven Multitasking laufen"?
Tom schrieb: > weil es Threads > gibt, die zu einem beliebigen Zeitpunkt einen anderen Thread > unterbrechen können müssen. Wie soll thread A durch thread B zu einem beliebigen Zeitpunkt unterbrochen werden können, wenn thread B gar nicht laufen soll, während thread A läuft?
:
Bearbeitet durch User
Bei Solaris-Threads gibt es thr_suspend() ... vllt ist so etwas auch im WinAPI verfügbar. Bei pthreads hilft man sich, indem man ein Signal an den anderen Thread sendet (nicht SIGSTOP, was den ganzen Prozess anhält), etwa SIGUSR1 und SIGUSR2 und in den Signalhandlern busy-waiting macht. Evtl auch ähnlich im WinAPI machbar. Aber: Du wirst wahrscheinlich Deadlock bekommen ... viel Spaß ;-) Wie schon gesagt wurde: der Ansatz ist schon im Ansatz falsch!
Tom schrieb: > Aber wie oben > geschrieben, möchte ich hier auf die eigentliche Applikation nicht > weiter eingehen. Scheint ja eine geniale Erfindung zu werden. Dann viel Spass beim Waschen mit Sand, da wirst du nicht nass und soll angeblich auch sauber machen :-)
Wenn es nur darum geht, irgendeinen Test durchzuführen, z.B. zur Fehlersuche, dann kannst Du ggf. im BIOS des PCs auch alle weiteren Kerne sowie Hyperthreading deaktivieren.
Tom schrieb: > Gibt es mit Hilfe der Windows API eine Möglichkeit zu verhindern, das > Threads gleichzeitig ausgeführt werden? Siehe MSDN Doku zu: EnterCriticalSection() LeaveCriticalSection() Wobei das obige dasselbe ist wie ein Mutex. Lies Dich mal in das Thema ein, das kann schnell komplex werden.
Jim M. schrieb: > Wobei das obige dasselbe ist wie ein Mutex. Lies Dich mal in das Thema > ein, das kann schnell komplex werden. nein, ein Mutex ist global. Geht bis aufs Betriebssystem. Ist damit langsamer. eine CriticalSection ist nur für die Anwendung und wird direkt von der msvrt breitgestellt. Sie machen beide das gleiche, aber sind doch verschieden.
Lustige Antworten dabei ;-) ...und nein, das hat nichts mit Freitag zu tun. Ok, dann muss ich das doch näher erklären: Auf einem uC hat man nur einen Core, kein Hyperthreading oder ähnliches. D.h. Ich kann zwar dort ein RTOS haben mit mehreren Tasks und sogar Interrupts, die diese Tasks zu jedem möglichen Zeitpunkt unterbrechen können. Aber ich weiß das niemals Task Code und Interrupt Code zur gleichen Zeit ausgeführt wird. Wenn ich dies auf dem PC simulieren möchte kann ich die Tasks und Interrupts auf Threads abbilden (und jetzt bitte keine Diskussionen über den näheren Sinn dahinter). Damit das aber funktioniert darf immer nur ein Thread zu gleichen Zeit ausgeführt werden. Rufus Τ. F. schrieb: > Definiere "Gleichzeitig". > > Gleichzeitig im Sinne von "auf mehreren Kernen parallel laufen" oder im > Sinne von "im präemptiven Multitasking laufen"? Im Sinne von auf mehreren Kernen parallel laufen. Md M. schrieb: > Wie soll thread A durch thread B zu einem beliebigen Zeitpunkt > unterbrochen werden können, wenn thread B gar nicht laufen soll, während > thread A läuft? Thread B darf laufen, aber wenn Thread B läuft darf Thread A nicht weiterlaufen solange Thread B läuft. Andreas S. schrieb: > Wenn es nur darum geht, irgendeinen Test durchzuführen, z.B. zur > Fehlersuche, dann kannst Du ggf. im BIOS des PCs auch alle weiteren > Kerne sowie Hyperthreading deaktivieren. Ich weiß leider nicht, auf welcher Hardware die Applikation später läuft. Es geht also nicht nur um einen Test sondern darum wie ich Windows per API beibringen kann die Threads meiner Applikation nicht parallel auszuführen. Ich bin mir durchaus bewusst, das die Antwort auch sein kann, das ist Blödsinn und geht gar nicht.
Tom schrieb: > . Es geht also nicht nur um einen Test sondern darum wie ich > Windows per API beibringen kann die Threads meiner Applikation nicht > parallel auszuführen. das willst du aber nicht > Ein Locken > durch Mutex/Semaphore kann ich leider auch nicht machen, weil es Threads > gibt, die zu einem beliebigen Zeitpunkt einen anderen Thread > unterbrechen können müssen. beides widerspricht sich.
Tom schrieb: > Md M. schrieb: >> Wie soll thread A durch thread B zu einem beliebigen Zeitpunkt >> unterbrochen werden können, wenn thread B gar nicht laufen soll, während >> thread A läuft? > > Thread B darf laufen, aber wenn Thread B läuft darf Thread A nicht > weiterlaufen solange Thread B läuft. Hab ich verstanden. Meine Frage war ja eben, wie es da zu einer Situation kommen kann, in der B durch A unterbrochen werden könnte? Tom schrieb: > weil es Threads > gibt, die zu einem beliebigen Zeitpunkt einen anderen Thread > unterbrechen können müssen.
Tom schrieb: > Wenn ich dies auf dem PC simulieren möchte kann ich die Tasks und > Interrupts auf Threads abbilden (und jetzt bitte keine Diskussionen über > den näheren Sinn dahinter) Prima, es wird immer besser, genau der Knackpunkt deines Problems soll nicht diskutiert werden. Nun gut schönes Wochenende :-)
Beitrag #5000074 wurde von einem Moderator gelöscht.
Peter II schrieb: > Tom schrieb: >> . Es geht also nicht nur um einen Test sondern darum wie ich >> Windows per API beibringen kann die Threads meiner Applikation nicht >> parallel auszuführen. > > das willst du aber nicht ;-) Danke, ich weiß schon was ich will. Md M. schrieb: > Hab ich verstanden. Meine Frage war ja eben, wie es da zu einer > Situation kommen kann, in der B durch A unterbrochen werden könnte? Ok, sagen wir Thread A bildet ein Task ab und führt irgendwelche Operationen durch. Thread B bildet einen Interrupt ab und legt sich mit Sleep() am Ende wieder für 1 msec schlafen. D.h. zu einem beliebigen Zeitpunkt während Thread A läuft, läuft jetzt auch Thread B. Ich möchte aber das zu dem Zeitpunkt Thread A nicht weiterläuft, sondern Thread B erst wieder bis zum Sleep() läuft und erst dann wieder Thread A weiterläuft. D.h. das Scheduling soll sich so verhalten als würde es nur einen logischen bzw physischen Core geben. Der Andere schrieb: > Prima, es wird immer besser, genau der Knackpunkt deines Problems soll > nicht diskutiert werden. > Nun gut schönes Wochenende :-) Korrekt, letztlich geht es nur um eine einfache Frage zu Windows. Es geht nicht darum, wieso dieses Problem besteht. Prima, das du das schon verstanden hast. Dir auch ein schönes Wochenende ;-).
Beitrag #5000101 wurde von einem Moderator gelöscht.
Tom schrieb: > Sleep() am Ende wieder für 1 msec schlafen. D.h. zu einem beliebigen > Zeitpunkt während Thread A läuft, läuft jetzt auch Thread B. Ich möchte > aber das zu dem Zeitpunkt Thread A nicht weiterläuft, sondern Thread B > erst wieder bis zum Sleep() läuft und erst dann wieder Thread A > weiterläuft. D.h. das Scheduling soll sich so verhalten als würde es nur > einen logischen bzw physischen Core geben. dann mache doch ein Lock was vor dem sleep geunlockt wird. und beim sleep wieder gelockt wird.
Tom schrieb: > Prima, das du das schon verstanden hast. Ich habe die Prinzipien und Grenzen von Multitasking schon verstanden als du wahrscheinlich noch das kleine Einmal Eins geübt hast und verdiene damit unter Anderem seit über 20 Jahren meine Brötchen. Angefangen mit "kooperativem Multitasking" unter Win3.x und den ersten 'richtigen' Multitasking auf auf PCs mit OS/2 1.3 und später WIN NT 3.0. Du darfst dich aber gerne über uns und/oder unsere Antworten hier lustig machen. Was bleibt dir sonst denn DEIN Problem wird so nicht gelöst :-) Und Tschüss, ich muss jetzt in den wohlverdienten Urlaub
In einer VM ausführen und dieser nur einen CPU-Kern zuweisen?
Der Andere schrieb: > Und Tschüss, ich muss jetzt in den wohlverdienten Urlaub Den scheinst du auch dringend zu brauchen. Wieso fühlst du dich angegriffen und machst den TO an? Er hat sein Problem beschrieben und dann selbst Antworten wie: TestX schrieb: > Kurzgesagt was du vorhast macht keinen sinn und ist übelster > schwachsinn...freitag halt mit Humor genommen. Wieviel Smilys soll er denn noch dahinter machen? Also einfach mal locker und freundlich bleiben.
Jan H. schrieb: > In einer VM ausführen und dieser nur einen CPU-Kern zuweisen? Danke aber das geht leider nicht, weil ich keinen Einfluß darauf haben, wo die Applikation später läuft. Ich wäre mir auch nicht sicher, ob der eine CPU-Kern in der VM Hyperthreading macht? Zum Testen ist das aber ein guter Vorschlag.
Ein Thread kann jederzeit unterbrochen werden, und ein anderer fortgesetzt werden. Es ist vollkommen egal, ob es einen oder mehrere Kerne gibt, ein Programm bekommt davon nichts mit. Solange zwei Theread an jeder stelle unterbrochen werden können, egal wieviele Kerne oder sonstiges, kann jedes resultat herauskommen, das auch bei gleichzeitiger ausführung herauskommen hätte können. Ohne zu wissen was du brauchst kann ich dir aber nicht weiter helfen. Am Ende willst du eventuell nur einen event-loop oder signale neu erfinden? (wobei beides so verschieden ist, das es nie in den selben Satz gehört)
eventuell mit https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx Stefan
Aus: https://superuser.com/questions/309617/how-to-limit-a-process-to-a-single-cpu-core Dies sieht vielversprechend aus: start /affinity 1 program.exe (... und 20 andere Methoden)
Vielleicht reden auch nur alle aneinander vorbei... der Threading Mechanismus unter Windows hat die Eigenschaft, dass Prioritäten unterhalb der Realtime Priority Classes durch einen dynamischen Boost Mechanismus zuweilen doch eine höhere Priorität bekommen können, um nicht komplett zu verhungern. Vielleicht ist der TO nur auf diese Eigenart hereingefallen? Lösung in diesem Fall: Deine relevanten Prioritäten in die Echtzeitkategorie legen. Hat natürlich signifikante Auswirkungen auf den Gesamtdurchsatz (also auch der Anderen Applikationen). Das ist ja aber auch so gewollt, deswegen heissen diese Prios ja Realtime (obwohl sie das natürlich im Sinne eines wirklichen RTOS nicht sind).
Stefan schrieb: > eventuell mit > > https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx > > https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx > > Stefan Und dazu noch https://msdn.microsoft.com/en-us/library/windows/desktop/ms686345(v=vs.85).aspx und https://msdn.microsoft.com/en-us/library/windows/desktop/ms685086%28v=vs.85%29.aspx
Ruediger A. schrieb: > Vielleicht reden auch nur alle aneinander vorbei... > > der Threading Mechanismus unter Windows hat die Eigenschaft, dass > Prioritäten unterhalb der Realtime Priority Classes durch einen > dynamischen Boost Mechanismus zuweilen doch eine höhere Priorität > bekommen können, um nicht komplett zu verhungern. Vielleicht ist der TO > nur auf diese Eigenart hereingefallen? > > Lösung in diesem Fall: Deine relevanten Prioritäten in die > Echtzeitkategorie legen. Hat natürlich signifikante Auswirkungen auf den > Gesamtdurchsatz (also auch der Anderen Applikationen). Das ist ja aber > auch so gewollt, deswegen heissen diese Prios ja Realtime (obwohl sie > das natürlich im Sinne eines wirklichen RTOS nicht sind). Danke, ich denke das geht in die richtige Richtung, und tatsächlich schalte ich schon das Priority Boosting ab. Ich denke, da keine andere Antwort kam, gibt es keine andere Möglichkeit als mit SetThreadGroupAffinity() zu arbeiten. Leider ist mir nicht ganz klar, wie der Windows Scheduler arbeitet. Also, ob er den Prozess/Threads, die mit SetThreadGroupAffinity() auf einen logischen Core gebunden werden, nur auf diesem ausführt oder ob das nur ein Hinweis ist und der Scheduler einen Thread doch mal auf einem anderen Core ausführen kann und damit doch wieder zwei Threads parallel ausgeführt werden.
Tom schrieb: > Leider ist mir nicht ganz > klar, wie der Windows Scheduler arbeitet Auch wenn du es wüsstest, solltest du dich nicht 100%ig drauf verlassen. Gerade Scheduler gehören zu den Teilen eines Betriebssystems, die die Entwickler gerne mal ändern. Georg
Md M. schrieb: > Tom schrieb: >> weil es Threads >> gibt, die zu einem beliebigen Zeitpunkt einen anderen Thread >> unterbrechen können müssen. > > Wie soll thread A durch thread B zu einem beliebigen Zeitpunkt > unterbrochen werden können, wenn thread B gar nicht laufen soll, während > thread A läuft? Indem ein thread den nächsten aus dem Tiefschlaf holt und sich selbst hinlegt. Suspend und Resume waren es glaub ich
Starte einen Extra-thread welcher periodisch einen Thread mit "SuspendThread" schlafen legt und den anderen mit "ResumeThread" weiterlaufen lässt.
Mike B. schrieb: >> Wie soll thread A durch thread B zu einem beliebigen Zeitpunkt >> unterbrochen werden können, wenn thread B gar nicht laufen soll, während >> thread A läuft? > > Indem ein thread den nächsten aus dem Tiefschlaf holt und sich selbst > hinlegt. Suspend und Resume waren es glaub ich Das ist für mich irgendwie immer noch nicht nicht "ein thread unterbricht einen anderen zu einem beliebigen Zeitpunkt".
Mal ein paar u.U. zielführendere Links, da es z.T. auf so etwas wie einen eigenen Scheduler hinausläuft: User Mode Scheduling (nur für 64-Bit-Anwendungen) https://msdn.microsoft.com/en-us/library/windows/desktop/dd627187(v=vs.85).aspx bzw. Fibers https://msdn.microsoft.com/en-us/library/windows/desktop/ms682661(v=vs.85).aspx
Beitrag #5001056 wurde vom Autor gelöscht.
Oder gar nicht mit dem Schedular anfangen... Gibt ja unter Windows Libraries, die Unix-Signale emulieren. Die ganze Arbeit im selben Thread machen. Die anderen Threads senden nur Signale und die Arbeit dieser Threads wird dann im Signal-Handler gemacht.
Es gibt auch FreeRTOS für Windows. Das macht eigentlich exakt das Gewünschte, inklusive Simulation von ISRs. Das könnte man nutzen, oder zumindest könnte man es auf die gleiche Art machen. Siehe http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
:
Bearbeitet durch User
ich mutmaße mal ein wenig: Der OP möchte sein µC-OS am PC simulieren. Dazu will er in einem Thread die Programm-Logik laufen lassen und in mindestens einem Anderen die Peripherie simulieren, die Interupts generiert. Ich würde folgendes probieren: - Thread mit Programmlogik (Mainloop) (im Folgenden PLT - program logic thread) starten - Thread(s) mit Interuptsimulation (im Folgenden IST - interupt simulation thread) starten die ISTs könnten nun folgendermaßen arbeiten: - ein gemeinsames großes Flag"register" mit möglichen Interupts - beliebige Threads, die sich um die Simulation kümmern und entsprechend die Flags in diesem Register setzen - Der Main-IST hat eine Schleife, die kontinuierlich testet, ob Interupts zu simulieren sind. (ob er zwischen diesen Tests sich selbst um die Peripherie-Sim kümmert, oder wirklich nur die Flags checkt, wäre abzuwägen - zumindest Timer könnte er nebenbei selbst erledigen) Liegen Interupts an, sollte der IST folgendes tun: - 'SuspendThread' auf den PLT - ISR Aufrufen - 'ResumeThread' auf PLT
:
Bearbeitet durch User
Vlad T. schrieb: > ich mutmaße mal ein wenig: > > Der OP möchte sein µC-OS am PC simulieren. ...also wenn es wirklich darum gehen sollte... https://msdn.microsoft.com/en-us/library/ms810431.aspx (Vorsicht AAAAALT)
Tom schrieb: > Ok, dann muss ich das doch näher erklären: > Auf einem uC hat man nur einen Core, kein Hyperthreading oder ähnliches. > D.h. Ich kann zwar dort ein RTOS haben mit mehreren Tasks und sogar > Interrupts, die diese Tasks zu jedem möglichen Zeitpunkt unterbrechen > können. Aber ich weiß das niemals Task Code und Interrupt Code zur > gleichen Zeit ausgeführt wird. > Wenn ich dies auf dem PC simulieren möchte kann ich die Tasks und > Interrupts auf Threads abbilden (und jetzt bitte keine Diskussionen über > den näheren Sinn dahinter). Damit das aber funktioniert darf immer nur > ein Thread zu gleichen Zeit ausgeführt werden. Nein. Du hast das Problem noch nicht wirklich verstanden, aber deine Gedanken gehen wohl schon in die richtige Richtung. Lösung: Du musst die eigentliche Simulation der µC-Umgebung in einen eigenen Prozess auslagern und diesen fest an exakt einen Core nageln. Keine Ahnung, was nun noch die anderen Threads tuen, die du in deinem eigenen Prozess noch verbleibend hast und von denen du glaubst, dass sie die Simulation stören würden. Mit der Simulation der Zielumgebung direkt können sie ja absolut nix zu schaffen haben, sonst wären sie jetzt in dem anderen Prozess... Die eigentliche Lösung dürfte also darin bestehen, deine Bugs zu beseitigen, die in genau diesen Threads stecken dürften... Have fun...
Mike B. schrieb: >> Wie soll thread A durch thread B zu einem beliebigen Zeitpunkt >> unterbrochen werden können, wenn thread B gar nicht laufen soll, während >> thread A läuft? > > Indem ein thread den nächsten aus dem Tiefschlaf holt und sich selbst > hinlegt. Suspend und Resume waren es glaub ich Das klingt nicht nach Threads, sondern nach kooperativem Multitasking, besser bekannt als "Coroutines". Nicht dass ich wüsste, ob Windows sowas kann. Aber vielleicht hilft dir das Stichwort weiter.
Tom schrieb: > als mit SetThreadGroupAffinity() zu arbeiten. Das wäre allerdings wohl die falsche Funktion, mit 'SetThreadAffinityMask' könntest Du mehr Glück haben.
tictactoe schrieb: > Das klingt nicht nach Threads, sondern nach kooperativem Multitasking, > besser bekannt als "Coroutines" Dass Thread B den Thread A unterbricht, kann ja auch garnicht eine Funktion des des Thread B alias Interrupt Service sein, das ist das was im Controller die Interrupt-Hardware tut. Diese müsste wohl in einem zusätzlichen Thread simuliert werden, für einen Timer z.B. müsste alle x ms Thread A gestoppt und Thread B vom Anfang an neu gestartet werden. Nach Ablauf der Funktion von Thread B beendet sich dieser und sendet dem Thread A einen resume-Befehl (=Return from Interrupt). Andere Interrupts wie ADC oder UART sind noch komplexer zu simulieren, fraglich, ob sich der Aufwand lohnt. Im Prinzip bräuchte man Simulationsthreads für die gesamte Peripherie-Hardware des Controllers. Am Ende hat man mehr Fehler in der Simulation als in dem was untersucht werden soll, und man sucht sich tot an Stellen die für das Produkt irrelevant sind. Georg
guest schrieb: > Tom schrieb: >> als mit SetThreadGroupAffinity() zu arbeiten. > > Das wäre allerdings wohl die falsche Funktion, mit > 'SetThreadAffinityMask' könntest Du mehr Glück haben. Klar, hast Recht, keine Ahnung wie ich auf SetThreadGroupAffinity() kam. Ich war mir bis jetzt nicht sicher, ob ich über "Affinity" wirklich sicher sein kann, das Windows sich auch daran hält. Wie verhält sich das, wenn ich mit SetProcessAffinityMask() den Prozess auf Core 1 binde. Kann ich dann davon ausgehen, das all Threads in diesem Prozess auch auf Core 1 gebunden sind?
Tom schrieb: > Wie verhält sich das, wenn ich mit SetProcessAffinityMask() den Prozess > auf Core 1 binde. Kann ich dann davon ausgehen, das all Threads in > diesem Prozess auch auf Core 1 gebunden sind? ja aber das alles hilft ja dem OP nicht. Auf das Scheduling zwischen den Threads hat er ja trotzdem keinen Einfluss. Ich habe oben einen möglichen Weg skizziert. Ein eventueller anderer wäre das Benutzen der Fiber-API
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.