"We are back" « oc.at

[c#/.net] windows thread und method interrupt

3mind 25.08.2008 - 07:02 1578 7
Posts

3mind

mimimi
Avatar
Registered: Sep 2004
Location: 1030
Posts: 1594
puh, ich versuch mein problem mal auf das wesentlichste zu beschränken, um nicht noch mehr verwirrung aufkommen zu lassen:

kennt jemand von euch einen weg mit .net bzw. in diesem fall c#, sich den aktuellen "zustand" eines threads zu speichern und später wieder an diese stelle zurückzuspringen?
mit zustand meine ich die aktuelle ausführung (also auch wo er in der jew. methode grade ist) inkl. variablen vom stack etc.

wichtig ist, dass der thread dabei nicht pausiert werden soll!

ich weiß, das ganze ist recht zach, aber trotz mehrstündiger research bin ich bisher auf keinen grünen zweig gekommen, vielleicht hat ja einer von euch eine idee?

FYI: bisher ist das ganze lowlevel mit C implementiert, dort ist ausführen von asamber (_asm) und verwenden von setjmp/longjmp möglich. jetzt soll eben erruiert werden ob das ganze auch in der windows-umgebung möglich ist.


tia für _alle_ meinungen und vorschläge!

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11342
C# hat doch eh seit einiger Zeit Closures?

Was genau hast du vor?

3mind

mimimi
Avatar
Registered: Sep 2004
Location: 1030
Posts: 1594
ok, es geht grob gesagt um die portierung eines microcontroller-OS auf .net zum zweck der simulation.

ein thread soll dabei ein komplettes task-system abbilden. ein task hat eine methode die er immer wieder abarbeitet. ist er fertig sucht er sich automatisch den nächsten task. die schwierigkeit dabei ist dass es auch zu timer-interrupts kommen kann, die ein task-weiterschalten erzwingen. dabei merkt sich das OS alle variablen vom stack, den stackpointer und lädt diese bei wiederbetreten des tasks um dort weiterzumachen wo man zuvor aufgehört hat.

natürlich könnte man jeden task als eigenen thread abbilden, meine aufgabe ist es jedoch zu untersuchen ob man auch mit 1 thread (bzw. einen zweiten der dann die timer-interrupts generiert) auskommt.

hoffe das ist halbwegs verständlich.

vanHell

Tauren Marine
Registered: May 2004
Location: Hell
Posts: 1017
Auch wenn ich glaub das ich dein Problem verstehe hab ich nicht sehr viel ahnung davon.
Aber ist Thread.Interrupt und ThreadExceptionEventHandler eine option. Ansonsten kann man auch noch mit .Net IL Asm programmiern wenn das was bringt *duck*

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11342
Also du willst aus einem Thread einen anderen Thread auf einen anderen Kontext umschalten, und der soll währenddessen weiterlaufen?

Zitat
wichtig ist, dass der thread dabei nicht pausiert werden soll!

Da glaub ich kaum dass das geht. IMHO geht maximal: anhalten, umschalten, weiterlaufen lassen.

Im Win32 API gibts Fibers für sowas, die sind aber AFAIK nicht sauber im .Net nutzbar (bzw. gibts sogar im Native Code eine ganze Menge Einschränkungen).

Die Alternative, die immer geht, ist, den Stack überhaupt nicht zu verwenden und den ganzen Code als Statemachine zu schreiben, die man nach jedem Schritt unterbrechen kann. Vielleicht hilft dabei ja auch ein "yield return".

FastForward

Little Overclocker
Registered: Apr 2001
Location: Wien
Posts: 60
Hi 3mind!

Wenn du die Logik umdrehst, könnte es gehen: Soll heissen, dass der aktuell laufende Task nach jeder Sourceline den Timer-Thread frägt, ob ein Timer-Interrupt aufgetreten hat. Das ist ein normaler Methodenaufruf der selbständig den aktuellen Zustand wegsichert. Dieses 'Nachfragen' muss ja nicht unbedingt vom Task-Entwickler eingefügt werden. Du könntest das ja vor dem Compilieren in Form von Sourcelevel-Weaving oder Bytecode-Weaving (siehe AOP = Aspect Oriented Programming) umsetzen. Wenn du's Sourcelevel-Weaving machst, hättest vielleicht sogar noch den Vorteil, dass die Statements atomic sind, was sich mit Bytecode-Weaving wesentlich schwerer umsetzen liese. Der Nachteil ist natürlich, dass du nicht beliebig zwischen den Tasks hin und her schalten kannst. Nach einem Interrupt wird der Thread fortgesetzt, der zuletzt unterbrochen wurde (normales Callstack unwinding). Aber vielleicht ist das eh keine Requirement. Task-Prioritäten lassen sich damit garnicht oder nur mit größerem Aufwand umsetzen.

Desweitern ist es möglich und erlaubt in .NET-Assemblies auch nativen Win32-Code einzufügen. Mir fällt dazu zwar keine mögliche Lösung ein, aber vielleicht triggert das ja bei jemand anderen was.

Du könntest dir auch selbst einen Interpreter schreiben, der die Tasks zur Laufzeit in Source-Junks (zB in Statements, Lines oder Blocks) aufsplittet und per Reflection ausführt. Dann kannst du nach jedem abgearbeiteten Junk das Auftreten eines Interrupts überprüfen und entsprechend reagieren.

Das Ergebnis deiner Evaluation wäre sehr interessant.

lg
FF

3mind

mimimi
Avatar
Registered: Sep 2004
Location: 1030
Posts: 1594
vielen dank schonmal für all die hilfreichen vorschläge und tipps.
ich werd alle themen mal überdenken - sollte es neue erkenntnisse geben meld ich mich wieder.

Xetrill

Little Overclocker
Avatar
Registered: Dec 2004
Location: Wien
Posts: 85
Interessante Aufgabe …
Mein Verständnis davon ist sicher nicht das beste, aber ich bin grad auf folgendes gestoßen.

Zitat
Coroutines are a powerful feature of many programming languages including CLU, Scheme, Python, Ruby, and ICON. Coroutines can save processor overhead and reduce redundancy because they allow you to stop execution of a procedure midstream, return a value, and resume exactly where the procedure left off.

This article shows how coroutines can be implemented for the .NET Framework by using the Fiber API and Managed Extensions for C++, and how they can be easily used with other .NET-compliant languages. This article also shows a sophisticated use of the runtime host for running multiple managed threads on a single OS thread.
Implementing Coroutines for .NET by Wrapping the Unmanaged Fiber API

HTH.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz