_beginthreadex Error
-
Dann poste halt mal ein Minimalbeispiel, welches das Problem reproduziert. Haben keine Lust hier rumzuraten, was du in deinem Code treibst!
-
Debugge doch einfach mal rein bis zu CreateThread und schau Dir den "richtigen" Fehlercode an!!!!!!
-
Kann es sein, dass man ein Thread mit
_beginthreadex(NULL,0, Warten,this, 0, &ThreadID);nicht öfters in kurzer Zeit nach einander erstellen darf/kann?
Ich habe mein Programm nochmal völlig umgeschrieben und mir ist aufgefallen, dass wenn ich ein paar Millisekunden warte, dann klappt das!
Woran kann das liegen?Ich starte jetzt auch nur noch max 5 Threads!
-
Ähhh... habe ich mich nicht deutlich ausgedrückt?
Reindebuggen?PS: Und wenn Du Threads in "ms" Abstand erstellst ist mir klar, das Du Probleme bekommst... Du kannst nur eine bestimmte (kleine) Anzahl an Threads pro Prozess erstellen!
-
Jochen Kalmbach schrieb:
Du kannst nur eine bestimmte (kleine) Anzahl an Threads pro Prozess erstellen!
Wie klein kann denn die Anzahl sein?
Ich habe mal gelesen, dass man so ca. 1000 Threads erzeugen kann.
Denn ich merke gerade, dass bei dem 5. Thread, den ich starten möchte, der Fehler auftritt!
Ich ereuge diese Thrads direkt nacheiandner in dem Hauptprozess (TForm1).
Kann ich das irgendwie umgehen oder hinbekommen, dass ich mehr als nur 4 Thrads starten kann?
-
Kannst Du den Fehler nachvollziehen?
Auch im Debugger?
(Ich sage es zum letzten Mal): Debugge in die _beginthrtead... Funktion reinWenn Du es beim Debuggen nicht Nachvollziehen kannst, dann setzte in _beginthread.. einen Breakpoint, wo der Fehler festgestellt wird.
So findest Du sofort die *genaue* Ursache!
-
Beim Debuggen tritt kein anderer Fehler auf!
Ich sehe diesen Fehler ja nur, da ich ihn so abfrage:if(!_beginthreadex(NULL,stackgroesse, Bearbeiten,this,0, &ThreadID)) Form1->Erroraus("Bearbeiten",errno); ... void __fastcall TForm1::Erroraus(AnsiString Meldung,unsigned int Err) { AnsiString tmp; if(Err==ENOMEM) { tmp="ENOMEM"; } else if(Err==EAGAIN) { tmp="EAGAIN"; } else if(Err==EINVAL) { tmp="EINVAL"; } MessageBox(NULL,tmp.c_str(),("Error:"+Meldung).c_str() , MB_OK); }Achso: Komischer Weise tritt der Fehler jetzt erst bei dem 6. Aufruf (mehr wollte ich auch nicht erzeugen) auf, obwohl ich nichts geändert haben!
-
if(!_beginthreadex(NULL,stackgroesse, Bearbeiten,this,0, &ThreadID)) { DWORD dwLastError = GetLastError(); Form1->Erroraus("Bearbeiten",errno); }Und was sagt GetLastError an dieser Stelle?
-
Naja, das ist nicht unbedingt zielführend, da Du weisst ja nicht, was in "_beginthread" sonst noch alles gemacht wird!
Einfacher ist: Ersetze "_beginthread" durch "CreateThread" und rufe dann GetLastError, auf, wenn es schief ging!!!
-
Jochen Kalmbach schrieb:
Naja, das ist nicht unbedingt zielführend, da Du weisst ja nicht, was in "_beginthread" sonst noch alles gemacht wird!
Einfacher ist: Ersetze "_beginthread" durch "CreateThread" und rufe dann GetLastError, auf, wenn es schief ging!!!
_beginthreadex allokiert TLS-Speicher für die CRT-Datenstrukturen und ruft dann CreateThread auf. Im Fehlerfall wird der Speicher wieder freigegeben. Mehr passiert da nicht.
-
Er verwendet die Borland-CRT... ich hab sie halt nicht hier und müsste raten, was Borland da macht...
-
Also was soll ich nun machen?
Diese Fehlermeldung ist ja eine von dem Errorcodesatz von GetLastError, nur dass der in errno drin steht!
Also soll ich nu mal CreateThread antesten??
Denn mit dieser Funktion habe ich noch keine Erfahrungen!
-
Probiere doch erst einmal meinen Vorschlag. Wenn GetLastError nichts Vernünftiges ausgibt, dann machst Du es wie Jochen es vorgeschlagen hat.
-
GetLastError() gibt bei CreateThread den Fehler 8 raus:
8
ERROR_NOT_ENOUGH_MEMORY
Not enough storage is available to process this command.
-
Tja, dann liegt es wohl am fehlenden Speicher (vermutlich dem Stack).
Ich würde jetzt alles in den Threadfunktionen auskommentieren und nacheinander wieder freigeben, um den Verursacher zu finden.
-
Wie viel Speicher benützt denn Deine Applikation?
Ein Programm kannn z.B. Memory-Fragmentierung sein. Lass es mal unter WinDbg laufen und rufe mal
!address -summaryauf.
-
Okay machen wa es einfach mal so:
Ich habe diese beiden Threadfunktionen, wobei Bearbeiten nicht komplett ist aber alles, was ich bis jetzt nicht auskommentiert habe!
Wenn ich also erst 4x Bearbeiten und 1x MoveFiles aufrufe, dann tritt nach dem o.g. Aufruf der Fehler ENOMEM oder halt Fehlercode 8 auf!
Keine Sorgen, die beiden Funktionen sind nicht fertig und ich werde dort noch vieles anders machen, nur erstmal möchte ich diesen scheiss Error loswerden!Zu meinem System: Es hat 4 GB Arbeitsspeicher und 10 GB Auslagerungsdatei und daher kann es an dem Speicher NICHT mangeln, zudem verbraucht das Programm im Taskmanager gerade mal 3 MB!
unsigned __stdcall TForm1::Bearbeiten(void *param) { AnsiString* Dateiarray = static_cast<AnsiString*>(param); EnterCriticalSection(&cs); CSThreadAnz++; BearbeitenAnz++; LeaveCriticalSection(&cs); while(1) { if(BearbeitenAnz==1) { OpenSemaphore(SEMAPHORE_ALL_ACCESS,true,"ECBearbeiten"); } for(unsigned int z=1;z<atoi(Dateiarray[0].c_str());z++) { AnsiString Dateiname=Dateiarray[z]; int fileSize=atoi(Dateiarray[++z].c_str()); if(!(Dateiname.AnsiPos("\\tmp\\"))) { EnterCriticalSection(&cs3); CopylistFrom->Add(Form1->Frame31->Edit1->Text+"\\"+Dateiname); CopylistTo->Add(Form1->Frame31->Edit1->Text+"\\tmp\\"+Dateiname); LeaveCriticalSection(&cs3); } } WaitForSingleObject(OpenSemaphore(SEMAPHORE_ALL_ACCESS,true,"ECBearbeiten"),INFINITE); } return 0; } unsigned __stdcall TForm1::MoveFiles(void *param) { EnterCriticalSection(&cs); CSThreadAnz++; Kopieren=true; LeaveCriticalSection(&cs); while(1) { while(CopylistFrom->Count!=0) { EnterCriticalSection(&cs3); AnsiString From=CopylistFrom->Strings[0]; AnsiString To=CopylistTo->Strings[0]; CopylistFrom->Delete(0); CopylistTo->Delete(0); LeaveCriticalSection(&cs3); MoveFileEx(From.c_str(),To.c_str(),MOVEFILE_COPY_ALLOWED); AnsiString error=GetLastError(); if(80==error) MoveFileEx(From.c_str(),(To+"_"+Exists++).c_str(),MOVEFILE_COPY_ALLOWED); } WaitForSingleObject(OpenSemaphore(SEMAPHORE_ALL_ACCESS,true,"ECBearbeiten"),INFINITE); } EnterCriticalSection(&cs); CSThreadAnz--; Kopieren=false; LeaveCriticalSection(&cs); return 0; }
-
Hat denn keiner ne Ahnung, woran das liegen kann mit diesem Fehler??
-
So, ich habe endlich den Fehler beheben können!
Es lag an den Compilereinstellungen!Es gibt bei Borland noch eine Release- Konfiguration und ich habe einfach die Optionen an die Debug- Konfiguration angeglichen, sodass ich aber noch die Debug- Funktionen habe!
-
Scherz?