Threadprobleme
-
Ich würde mal behaupten das mit dem WaitForSingleObject sollte nicht das Problem denn da ist ein Timeout definiert. Weit aus Kritischer seh ich das beenden, Die Variable clicked wird nei auf false gesetzt also läuft der Thread weiter, dann kommt die Abfrage auf den Exitcode, die total belanglos weil nicht ausgewertet, und zum schluß damit das alles noch Rund wird schießt du einfach den Thread ab, wobei ich vermute das da irgendwas schief geht dalso der noch läuft wärend Speicherbereiche schon nicht mehr existent sind oder so.
if(clicked==true) { clicked = false; DWORD lpExitCode; //hier jetzt ne schleife oder so und warten das sich der Thread selbst beendet sollte er das in einer gewissen Zeit nicht dann erst TerminateThread GetExitCodeThread(hThread,&lpExitCode); TerminateThread(hThread,lpExitCode); } else { clicked = true; hThread = CreateThread(NULL,0,ThreadFunc,NULL,0,NULL); WaitForSingleObject(hThread,100); }
-
ihoernchen schrieb:
x = new int []; y = new int [];
Wie groß sind deine Arrays?
Naja, das kommt ja darauf an wie lange ich Daten generieren lasse. Wenn ich den Button einmal anklicke fängt die Datengenerierung an und wenn ich ein zweites mal klicke soll es wieder aufhören. Ich habe eine Verzögerung eingebaut, Sleep(50);, damit nicht zu viele Daten generiert werden. Wie groß die Verzögerung am Ende sein wird, weis ich aber noch nicht. Das heißt die Arrays müssen ganz schön was einstecken.
ihoernchen schrieb:
Du brauchst so einen "Schutz" (critical section) nur, wenn Threads sich "absprechen" müssen. Z.B. wenn Daten in einem Thread verändert und in einem 2. ausgewertet / angezeigt / was auch immer werden. Lokale Daten, die nur in dem Thread bekannt sind (wie in deinem Thread) müssen nicht abgesichert werden.
Die Variable clicked brauch keine Absicherung.Hm, ja das ist mir eigentlich auch bekannt, aber ich wollte eben irgendwann auf den count Wert zugreifen und ihn in einem Edit-Feld anzeigen lassen. Das habe ich leider noch nicht geschafft, da es aus einem Thread raus anscheinend nicht so einfach geht Daten abzugreifen. Und irgendwann muss ich auch die x- und y-Werte abgreifen, dafür generiere ich sie ja eigentlich. Die sollen dann irgendwann auch mal übergeben werden. Bräuchte ich dann dafür eine Absicherung?
-
Du solltest auch nicht auf Daten eines Threads zugreifen sondern der Thread soll die Daten bereitstellen.
Von Thread aus eine Nachricht an das Fenster zur Anzeige im EDIT und gut ist es.
-
CTecS schrieb:
Weit aus Kritischer seh ich das beenden, Die Variable clicked wird nei auf false gesetzt also läuft der Thread weiter, dann kommt die Abfrage auf den Exitcode, die total belanglos weil nicht ausgewertet, und zum schluß damit das alles noch Rund wird schießt du einfach den Thread ab, wobei ich vermute das da irgendwas schief geht dalso der noch läuft wärend Speicherbereiche schon nicht mehr existent sind oder so.
Also das mit der clicked Variable sehe ich auch so, die hatte ich auch Anfangs zuerst auf false gesetzt. Ich dachte ja auch eigentlich dass es ausreichen würde die auf false zu setzten damit der Thread sich beendet, aber leider tut er das nicht. Den Exitcode brauche ich doch für die TerminateThread(), ohne den geht es doch nicht, oder? Also zumindest sagt mir der Kompiler dass die Funktion nicht nur einen Parameter akzeptiert. Naja und dann zu guter letzt muss ich den Thread doch abschießen, er beendet sich halt einfach nicht. Ich hab auch schon ganz viel darüber gelesen dass man das nicht machen soll, aber die Funktion muss ja für irgendwas gut sein.
CTecS schrieb:
if(clicked==true) { clicked = false; DWORD lpExitCode; //hier jetzt ne schleife oder so und warten das sich der Thread selbst beendet sollte er das in einer gewissen Zeit nicht dann erst TerminateThread GetExitCodeThread(hThread,&lpExitCode); TerminateThread(hThread,lpExitCode); } else { clicked = true; hThread = CreateThread(NULL,0,ThreadFunc,NULL,0,NULL); WaitForSingleObject(hThread,100); }
Ich verstehe warum ich das machen soll, aber was soll denn in der Schleife passieren? Wenn ich da die Abfrage GetExitCodeThread() reinpacke, geht es nicht weil er dann motzt dass der Speicher überläuft. Wenn ich ein Sleep() reinpacke gehts auch nicht. Und nur ne Schleife ohne Anweisung bringt ja auch nix, die läuft ja einfach super schnell durch.
-
Unix-Tom schrieb:
Du solltest auch nicht auf Daten eines Threads zugreifen sondern der Thread soll die Daten bereitstellen.
Von Thread aus eine Nachricht an das Fenster zur Anzeige im EDIT und gut ist es.Geht das dann trotzdem mit
SetDlgItemText();
? Weil so habe ich das bisher nicht hinbekommen.
-
Schon, wenn im Mainthread eine Nachrichtenschleife läuft und Du keine MFC Objekte benutzt, sondern Window Handles.
-
Hallo Leute,
ich muss euch nochmal um Hilfe bitten. Ich bekomme diese
Access Violation
einfach nicht weg. Sitz jetzt schon seit 4 Tagen da dran und kann mir einfach nicht erklären wie das kommt. Der Debugger zeigt in der "dgbheap.c" immer auf folgende Zeile:if (_BLOCK_TYPE(pHead->nBlockUse) >= 0 && _BLOCK_TYPE(pHead->nBlockUse) < _MAX_BLOCKS) { state->lCounts[_BLOCK_TYPE(pHead->nBlockUse)]++; state->lSizes[_BLOCK_TYPE(pHead->nBlockUse)] += pHead->nDataSize; }
Ich denke auch wie CTecS dass der Fehler wohl darin liegt dass sich der Thread nicht immer beendet. Das komische ist halt dass der Fehler nicht immer, aber meisstens auftritt. Manchmal bekomme ich einen
Access Violation
im Aufruflistenfenster, kann dann aber das Problem trotzdem ohne Probleme beenden. Manchmal hängt er sich aber auch auf wenn ich das Programm dann beenden will.
Ich kann leider auch nicht "Debug >> Threads" aufrufen, erst wenn ich das Programm beendet hab, aber dann sehe ich ja nicht mehr den Thread der während des Programms gestartet wurde und wieder beendet werden sollte.Ich weis wirklich nicht mehr weiter, bitte helft mir.
-
Poste doch mal den Code so wie er läuft. Der Schnipsel da oben: da fehlt die Array Größe und der Thread schreibt ins Array ohne sich darum zu kümmern wie groß es ist. Count läuft von 0 bis unendlich.
Ist das vielleicht das Problem?
-
Du wirst einen Überlauf im Heap haben. Dieser ist begrenzt und Du begrenzt Deine Schleife nicht. Integer sind schnell überlaufen.
Für Deinen Thread noch einen Hinweis, vielleicht ein anderer Ansatz über eine Struktur zum Datenaustausch. Dann brauchst Du ihn auch nicht terminieren, sondern er kann sich selber beenden (macht er immer bei return). Als Beispiel:typedef struct{ CWnd *cWnd; BOOL lpKillThread; char Transfer[255]; int TransferNr; } THREAD_INFO;
zB. *cWnd für Dein Editfeld.
UINT tThread(LPVOID lpParam) { // Get a THREAD_INFO pointer from the // parameter that was passed in. THREAD_INFO *lpThreadInfo = (THREAD_INFO *) lpParam;
Klappt bisher immer. Ansonsten kannst Du bei einem einzigen Thread Events nutzen und mit WaitForSingleObject(event,0) abfragen.
-
Wie schon mehrfach Festgestellt wurde ist deine Array-Definition eher unsinnig und das wird auch dein Problem sein, wenn du die Werte dir eh nicht Merken willst dann Sende diese doch per PostMessage an deinen Mainwindow. An sonsten würde ich das Speichern der Daten einer Array-Klasse wie CUIntArray überlassen, denn da besteht nicht die gefahr über den Stack hinaus zu arbeiten, bzw. du brauchst dich nicht um Speicherreservierung und Freigabe zu kümmern.