Variable im Register verändern
-
So, ich hab jetzt nochmal 3 Nächte drüber geschlafen.
Ich hab nochmal drüber nachgedacht und alles neu aufgesetzt.Jetzt habe ich also eine Endlosschleife in der ein Thread gestartet wird. Diesem möchte ich eigentlich nur sagen wir mal 30ms geben um dann wieder in die Endlosschleife zurückzukehren. Wie kann ich denn sagen "dir gebe ich immer 30ms"? Er soll eigentlich immer nur die Veränderung anschauen und dann wieder in die Endloschleife zurückkehren damit diese wieder von Vorne beginnen kann. Pro Schleifendutchlauf soll der Thread aber auch einmal gestartet werden, so lange soll dann der main Thread warten (also die 30ms).
Kann mir wer helfen das zu realisieren?
edit: Wieso wird mein Thread in der Endlosschleife eigentlich nur ein einziges mal aufgerufen, wenn ich keine Bedingung zum Aufrufen angegeben habe? Bei jedem weiteren Schleifendurchlauf wird der CreateThread Befehl eifach übergangen.
-
Ich kann dir nicht ganz folgen. Poste mal deinen überarbeiteten Code.
-
So wie mein Code jetzt aussieht hab ich ihn aber schon wieder überarbeitet. Ich bekomme momentan immer ein Access Violation. Außerdem wird der CreateThread Befehl beim debuggen immer erstmal einfach ignoriert und erst nach
fflush (stdout);springt er in den Thread. Das verstehe ich nicht warum er das macht. Sollte ja eigentlich zuerst den Thread abhandeln.
Ich debugge übrigens direkt mit VC++ 6.0#define WIN32_LEAN_AND_MEAN #include <js.h> #include <windows.h> #include <stdio.h> #include <windowsx.h> #include <stdlib.h> #include <iostream> #include <iomanip> using namespace std; CRITICAL_SECTION Section; HANDLE hThread; DWORD dwThreadID; jsJoystick *js; float *ax; DWORD WINAPI ThreadFunc(LPVOID data); int main (int argc, char **argv) { jsInit (); js = new jsJoystick (0); printf ("Joystick test program.\n"); printf ("~~~~~~~~~~~~~~~~~~~~~~\n\n"); if (js->notWorking ()) printf ("Joystick not detected\n"); else printf ("Joystick is \"%s\"\n\n", js->getName()); if (js->notWorking ()) exit (1); ax = new float [js->getNumAxes ()]; int j; printf ("+---------JS----------+----------------"); printf ("+\n"); printf ("| Btns "); for (j = 0 ; j < 3 ; j++) printf ("Ax:%d ", j); cout << "| Aenderung "; printf ("|\n"); printf ("+---------------------+----------------"); printf ("+\n"); while (1) { int b; int index = 0; js->read (&b, ax); printf ("| %04x ", b); for (j = 0 ; j < 3 ; j++) printf ("%+.1f ", ax[j]); InitializeCriticalSection(&Section); hThread = CreateThread(NULL, 0, ThreadFunc, (LPVOID)index, 0, &dwThreadID); WaitForSingleObject(hThread, 100); DeleteCriticalSection(&Section); printf ("|\r"); fflush (stdout); #ifdef WIN32 Sleep (1); #elif defined(sgi) sginap (1); #else usleep (1000); #endif } getchar(); return 0; } DWORD WINAPI ThreadFunc(LPVOID data) { int j; float aend[3] = {0, 0, 0}; float ausg[3] = {0, 0, 0}; cout << "| "; EnterCriticalSection(&Section); for (j = 0; j < 3; j++) printf ("%+.1f ", ausg[j]); for (j = 0; j < 3; j++) { while (0.01 < ax[j] || ax[j] < -0.01) { aend[j] = ax[j] * 5; ausg[j] += aend[j]; Sleep(1000); printf ("%+.1f ", ausg[j]); } } LeaveCriticalSection(&Section); return((DWORD)data); }
-
Ah, das mit dem Access Violation lag wohl daran dass ich dem Thread zu wenig Zeit gegeben habe. Hab jetzt auf 500ms raufgeschraubt und dann klappt das auch wunderbar.
-
laura84 schrieb:
Jetzt habe ich also eine Endlosschleife in der ein Thread gestartet wird. Diesem möchte ich eigentlich nur sagen wir mal 30ms geben um dann wieder in die Endlosschleife zurückzukehren.
Weshalb möchtest du das machen? Das ist höchstwarscheinlich keine gute Idee.
laura84 schrieb:
Er soll eigentlich immer nur die Veränderung anschauen und dann wieder in die Endloschleife zurückkehren damit diese wieder von Vorne beginnen kann.
Dann warte doch einfach bis der Thread fertig ist, quasi so ähnlich, wie du es jetzt schon machst. Natürlich kannst du auch die Schleifendurchläufe in der Thradfunktion nach oben begrenzen, falls es das ist was du möchtest.
laura84 schrieb:
Ah, das mit dem Access Violation lag wohl daran dass ich dem Thread zu wenig Zeit gegeben habe. Hab jetzt auf 500ms raufgeschraubt und dann klappt das auch wunderbar.
Wenn du in jedem Fall warte möchtest, bis der Thread fertig ist, nimm INFINITE als Zeit. Dann kannst du auch sicher sein, das immer nur ein Thread läuft und das "hin- und herspringen" entfällt. Du solltest dich vielleicht mal damit vertraut machen, wie multithreading funktioniert und wie man mehrere Threads mit VC++ 6.0 debugged. Ich verstehe noch nicht, wozu du genau die Threads brauchst. Ich denke, das was du machst könnte man auch in einem einzelnen Thread machen und du machst dir das Leben unnötig schwer.
-
siecpp schrieb:
Weshalb möchtest du das machen? Das ist höchstwarscheinlich keine gute Idee.
Dafür sind Threads doch da, oder? Zwei Dinge gleichzeitig zu tun.
siecpp schrieb:
Ich denke, das was du machst könnte man auch in einem einzelnen Thread machen und du machst dir das Leben unnötig schwer.
Das habe ich jetzt letzendlich auch gemacht. Funktioniert auch alles, aber eben relativ langsam. Erst fragt er den eigentlichen Wert ab, dann rechnet er die Veränderungen aus und dann fragt er wieder den Wert ab....
Dadurch geht die Anzeige immer nur sehr stockend voran, das wäre eben mit Threads nicht so gewesen, aber da habe ich das Anzeigen nicht hinbekommen, sonst alles. Und das Anzeigen funktioniert auch nur nicht weil zwischen den Threads immer willkürlich hin und her gesprungen wird, was ich immer noch nicht so ganz verstehe warum das passiert.
-
laura84 schrieb:
siecpp schrieb:
Weshalb möchtest du das machen? Das ist höchstwarscheinlich keine gute Idee.
Dafür sind Threads doch da, oder? Zwei Dinge gleichzeitig zu tun.
Mit meiner Aussage meinte ich, dass es keine gute Idee ist, einen Thread quasi von außen "abzuschießen" ohne zu wissen, was der gerade gemacht hat. Wo genau du etwas gleichzeitig machst ist mir auch nicht klar.
laura84 schrieb:
Und das Anzeigen funktioniert auch nur nicht weil zwischen Threads immer willkürlich hin und her gesprungen wird, was ich immer noch nicht so ganz verstehe warum das passiert.
Wann welcher Thread ausgeführt wird bestimmt nur der Scheduler des Betriebssystems (abgesehen davon, dass man einen Thread auch gezielt schlafen legen kann). Wenn die Funktionalität deines Programmes davon abhängt, in welcher Reihenfolge die Threads ausgeführt werden, machst du etwas grundlegendes falsch. In diesem Fall musst du eintsprechende Synchronisierung sicherstellen. Auf der anderen Seite benutzt du bereits einige Funktionen zur Synchronisierung.
Ist dir klar was folgende CodeZelen machen und warum du sie an dieser Stelle benutzt?WaitForSingleObject(hThread, 100); //... EnterCriticalSection(&Section); //.. LeaveCriticalSection(&Section);
-
Dei Access Violation lag übrigend wahrscheinlich daran das du ein
DeleteCriticalSection(&Section);in der Schleife machst. Das macht nicht den geringsten Sinn und führt dazu, dass wennn das
DeleteCriticalSection(&Section);vor dem
LeaveCriticalSection(&Section);ausgefürt wird das Programm abstürzt, weil die Section nicht mehr da ist. So wie du das vorher gemacht hast war das sinnvoller. Ich denke du solltest dir erstmal klar machen was eine critical Section ist und warum du die hier brauchst. Die meisten deiner Probleme haben ihren Ursprung vermutlich darin, dass dein Verständniss von Multithreading und Threadsynchronisation noch sehr lückenhaft ist. Wenn ich etwas Zeit habe werde ich mal einen Link raussuchen, wo das gut beschrieben ist.
-
siecpp schrieb:
Mit meiner Aussage meinte ich, dass es keine gute Idee ist, einen Thread quasi von außen "abzuschießen" ohne zu wissen, was der gerade gemacht hat.
Das habe ich auch schon gelesen und das sehe ich auch ein, aber das mache ich doch gar nicht, oder? Wenn ich ein
WaitForSingleObject(hThread, 1000);ausführe schieße ich den Thread damit doch nicht ab, oder?
siecpp schrieb:
Wenn die Funktionalität deines Programmes davon abhängt, in welcher Reihenfolge die Threads ausgeführt werden, machst du etwas grundlegendes falsch.
Naja, in meinen Threads sind ja auch ein paar "cout" Befehle drin und wenn die einfach völlig wirr hingeschrieben werden, macht das eben keinen Sinn mehr. Das ist ja das Grundlegende Problem. Ich bekomme die Ausgabe ja nur nicht hin weil die Threads ablaufen wie sie wollen, was auch eigentlich kein Problem wäre wenn keine "cout" Befehle drin stehen würden. Verstehst du?
siecpp schrieb:
Ist dir klar was folgende CodeZelen machen und warum du sie an dieser Stelle benutzt?
Ja das ist mir klar. Das mit dem
DeleteCriticalSection(&Section);war natürlich ein blöder Fehler von mir, das hätte ich bemerken müssen.
siecpp schrieb:
Die meisten deiner Probleme haben ihren Ursprung vermutlich darin, dass dein Verständniss von Multithreading und Threadsynchronisation noch sehr lückenhaft ist. Wenn ich etwas Zeit habe werde ich mal einen Link raussuchen, wo das gut beschrieben ist.
Hier auf meinem Schreibtisch liegen 4 dicke Bücher, darunter das von Charles Petzold und ich habe mir auch schon so einiges im Internet zusammen gesucht, aber wenn man etwas schnell erledigen muss, kann man halt nicht unbedingt vorher ein 1000 Seiten langes Buch lesen.
Ich bin einfach ein Quereinsteiger und hab natürlich so gut wie keine Ahnung, aber ich muss mich einfach momentan damit auseinandersetzten und dafür bin ich auch schon gar nicht schlecht. Ich nehme deine Hilfe natürlich gerne an und bin über jeden Link dankbar. Du hast mir bisher schon ganz toll geholfen ich hmöchte mich nur ein bisschen erklären damit du nicht denkst ich nutze hier wen aus. Also auf jeden Fall schonmal - Danke.
-
laura84 schrieb:
siecpp schrieb:
Mit meiner Aussage meinte ich, dass es keine gute Idee ist, einen Thread quasi von außen "abzuschießen" ohne zu wissen, was der gerade gemacht hat.
Das habe ich auch schon gelesen und das sehe ich auch ein, aber das mache ich doch gar nicht, oder?
Ne das machst du nicht. Ich hatte aber
laura84 schrieb:
Diesem möchte ich eigentlich nur sagen wir mal 30ms geben um dann wieder in die Endlosschleife zurückzukehren.
so verstanden, dass du das machen möchtest.
laura84 schrieb:
Wenn ich ein
WaitForSingleObject(hThread, 1000);ausführe schieße ich den Thread damit doch nicht ab, oder?
Ne, damit wartet der main Thread entweder 1000 ms oder bis sich der Thread hThread beendet hat. Ich weiss allerdings nicht was du damit bezwecken möchtest.
laura84 schrieb:
Naja, in meinen Threads sind ja auch ein paar "cout" Befehle drin und wenn die einfach völlig wirr hingeschrieben werden, macht das eben keinen Sinn mehr. Das ist ja das Grundlegende Problem. Ich bekomme die Ausgabe ja nur nicht hin weil die Threads ablaufen wie sie wollen, was auch eigentlich kein Problem wäre wenn keine "cout" Befehle drin stehen würden. Verstehst du?
Ja jetzt habe ich verstanden was du meinst. Die einzelnen Threads dürften sich eigentlich aufgrund der Critical Section nicht in die Quere kommen. Packe mal das erste cout auch in die Critical Section.
Das einzige was jetzt noch sein könnte, ist, dass der main Thread da irgendwie zwischenfunkt. Du könntes z.B. die Ausgabe des main Threads in die selbe critical section legen. Du musst dir allerdings klar machen, dass der massive Einsatzt von critical sections oder ähnlicher Barrierefunktionen den Vorteil von Multithreading zunichte macht. Dein Programm verbringt wahrscheinlich schon so 90% der Zeit in critical sections, was dazu führt, dass alle Threads bis auch einen warten.laura84 schrieb:
Hier auf meinem Schreibtisch liegen 4 dicke Bücher, darunter das von Charles Petzold und ich habe mir auch schon so einiges im Internet zusammen gesucht, aber wenn man etwas schnell erledigen muss, kann man halt nicht unbedingt vorher ein 1000 Seiten langes Buch lesen.
Das ist auch sicher nicht nötig. Das Problem ist, das Multithreading etwas total unintuitives ist. Damit tuen sich viele sehr schwer, was ich sehr stark gemerkt habe, als ich Kleingruppenübungen an der UNI gehalten habe. Das kann man nicht durch ausprobieren lernen sondern nur duch Studium der theoretischen Grundlagen. Für ein einfaches Verständniss ist aber garnich so viel theorie nötig.
laura84 schrieb:
Ich bin einfach ein Quereinsteiger und hab natürlich so gut wie keine Ahnung, aber ich muss mich einfach momentan damit auseinandersetzten und dafür bin ich auch schon gar nicht schlecht.
Das sollte auch keine Kritik sein sondern nur ein gutgemeinter Rat.
laura84 schrieb:
Du hast mir bisher schon ganz toll geholfen ich hmöchte mich nur ein bisschen erklären damit du nicht denkst ich nutze hier wen aus. Also auf jeden Fall schonmal - Danke.
Kein Problem. Ich lasse mir hier auch an anderen Stellen massiv helfen und versuche nur dafür etwas wieder zurückzugeben.
-
So, ich habs jetzt doch noch geschafft das Programm mit Threads aufzubauen.
Ich hab einfach die cout Befehle aus der ThreadFunc rausgenommen und in den main Thread geschoben. Da hätte ich auch echt früher drauf kommen können.
Das Programm ist aber deswegen trotzdem nicht schneller geworden, wie sollte es auch. Da ich ja immer 1 Sekunde warte um den neuen Wert zu addieren geht es ja nicht anders.