Ich wollte unechtes multitasking in c mithilfe eines Timers und einem
Signalhandler unter Linux Implementieren, um es später auf einen uC mit
Timerinterrupt zu portieren.
Aber das Programm tut etwas, das da einfach nicht steht:
Peter II schrieb:> was soll der mist mit den gotos?
Ich fand es schöner die Einzelnen Programmteile mit labeln zu
beschriften, als grosse unübersichtliche verschachtelte if und switch
strukturen zu verwenden. Die gotos erfüllen ihren zweck.
Ich hab diesen Fehler gerade gefunden:
Daniel A. schrieb:> Peter II schrieb:>> was soll der mist mit den gotos?>> Ich fand es schöner die Einzelnen Programmteile mit labeln zu> beschriften, als grosse unübersichtliche verschachtelte if und switch> strukturen zu verwenden. Die gotos erfüllen ihren zweck.
Wenn du den Programmfluss verschleiern willst nur zu.
TriHexagon schrieb:> Wenn du den Programmfluss verschleiern willst nur zu.
Wer keine Ahnung vom Programmieren hat, der kann sich mit gotos
natürlich übel seinen Code verunstalten. Es gibt aber Situationen, in
dene gotos durchaus übersichtlicher sind, und dann ist es auch sinnvoll,
diese einzusetzen. Mir ist nicht klar, was das mit verschleiern zu tun
hat - im Gegenteil.
radiostar schrieb:> Es gibt aber Situationen, in> dene gotos durchaus übersichtlicher sind,
da ist hier aber nicht der Fall. Der code ist damit sehr
unübersichtlich.
wenn man Funktionen beschreiben will, dann verwenden man
Prozeduren/Funktionen und nicht Labels.
Peter II schrieb:> wenn man Funktionen beschreiben will, dann verwenden man> Prozeduren/Funktionen und nicht Labels.
und nicht zu vergessen Kommentare.
radiostar schrieb:> TriHexagon schrieb:>> Wenn du den Programmfluss verschleiern willst nur zu.>> Wer keine Ahnung vom Programmieren hat, der kann sich mit gotos> natürlich übel seinen Code verunstalten. Es gibt aber Situationen, in> dene gotos durchaus übersichtlicher sind, und dann ist es auch sinnvoll,> diese einzusetzen. Mir ist nicht klar, was das mit verschleiern zu tun> hat - im Gegenteil.
Wenn man strukturiert in C programmiert, dann werden die Anweisungen
standardmäßig von oben nach unten ausgeführt. Ausnahme sind höchstens
Schleifen und Funktionen/Prozeduren. Bei der richtigen Einrückung hat
man dann noch quasi visuell den Programmablauf im Auge und kann einzelne
Abschnitte wie Schleifen einfach überspringen. Bei deinem gotos springst
du mal nach unten, mal nach oben und man muss ständig nach Labels
suchen. Das ist wie bei einem Buch in dem man sich ständig Verweise
anschauen muss, was den Lesefluss absolut abträglich ist.
Es gibt Fälle in dem Gotos angebracht sind, doch hier sehe ich keine.
c-liker schrieb:> Peter II schrieb:>> wenn man Funktionen beschreiben will, dann verwenden man>> Prozeduren/Funktionen und nicht Labels.> und nicht zu vergessen Kommentare.
Ok, ich werde mir sowieso einen neuen Ansatz überlegen müssen, und dass
Programm nochmal neu schreiben.
Es scheint folgendes zu passieren:
1) main
2) timer stackframe speichern
3) funktion threadX aufrufen
4) timer stackframe speichern
5) timer stackframe nach main widerherstellen
6) timer verlassen, zu main zurückkehren
7) timer stackframe speichern
8) timer stackframe nach timerX widerherstellen
-> Zerstört stäck weil:
* main
* 1. stackframe timer <-- ist bereits zurückgekehrt, alles
folgende existiert nichtmehr auf dem stack
* timerX
* 2. stackframe <-- widerherstellung zerstört den stack
Passt auch zur ausgabe von valgrind (im Anhang)
TestTriHexagon schrieb:> Bei deinem gotos springst> du mal nach unten, mal nach oben
Dan hast du meinen Code nicht sehr genau Angeschaut, Da springe ich
immer von oben nach unten, aber nie von unten nach oben.
Daniel A. schrieb:> TestTriHexagon schrieb:>> Bei deinem gotos springst>> du mal nach unten, mal nach oben>> Dan hast du meinen Code nicht sehr genau Angeschaut, Da springe ich> immer von oben nach unten, aber nie von unten nach oben.
Mhm hab noch mal drüber geschaut, hätte schwören können das es einen
Sprung nach oben gab. Na egal.
Wie Peter schon anmerkte sind Funktionen anstatt der Labels besser
geeignet. Aber das musst du wissen.
Bastler schrieb:> Longjmp restauriert doch auch den Stack-Pointer. Hab ich was übersehen,> oder wo werden die n Stacks verwaltet?
Nein, da hast du recht, deshalb zerstört der longjump ja den stack: die
stackframes sind zu dem zeitpunkt nichtmehr da, darum ist der
Stackpointer danach ja auch irgendwo im nirvana und der stack zerstört.
Für preemptive braucht man je Task einen eigenen Stack. Und etwas ASM um
ein setjump/longjump mit Stack-Umschaltung auf der jeweiligen Plattform
zu implementieren. Und unter Linux könnte es sein, daß der Stack nicht
beliebig auf dem Heap liegen darf, aber dazu könnte man die Task-Stacks
als lokale Variablen in main() definieren. Ob man dabei was lernt, das
auf dem μC weiterhilft? Who knows?
Oliver S. schrieb:> Um mal aufs ursprüngliche Problem zurückzukommen: Zähl mal nach, wie> viele Variablen namens current_thread es in deinem Programm gibt...
Die überzälige lokale variable habe ich bereits bemerkt:
Daniel A. schrieb:> Ich hab diesen Fehler gerade gefunden: