Fragen zum Arbeiten mit Thread

EriFo

Erfahrenes Mitglied
Ich hab in meinem Programm eine grosse Funktion in einen Thread ausgelagert, damit dieses nicht einfriert - klappt alles super.

Nun wollt ich aber mal ausprobieren, die Priorität zu setzten und den Thread zu Pausieren.
Das wollte aber nicht gehen und ich bekam immer Fehlermeldungen zurück.

Nun wollt ich mal fragen, da in meinem Thread nur eine einzige Funktion sehr lange läuft,
ob das ein Pausieren oder ändern der Priorität nicht möglich macht.
(wenn z.B. die Funktion vorher auf die Thread-Ebene zurück kehren müsste damit das geht oder so k.A. °^_^)
oder ob es doch gehen müsste.
Was den Source betrifft so bin ich mir ziehmlich sicher, das Alles seine Richtigkeit hat (alles streng koscher nach MSDN ^___^) aber wenn ihn jemand sehen möchte: einfach schreiben (und was ggf. auch)

M.f.G. Erik
 
Sollte eigentlich klaglos gehen. Wie pausierst du den Thread?
SuspendThread? Wenn ja, gibt der einen gültigen Wert zurück oder einen Fehlerwert?
 
Jap - exakt: mit Suspend Thread:

Code:
DWORD result = 0;
result = SuspendThread( thread_handle );

if (result == 0xFFFFFFFF)
   //--- ging nicht ---
else
   //--- ging ---
Der Code hat dieses Format. Laut MSDN kommt "0xFFFFFFFF" wenns nicht ging und das bekomm ich immer. Selbiges gilt für die Priorität (poste ich gleich mal mit ^_^):


Code:
BOOL result=0;
result = SetPriorityClass( thread_handle, priority_class);

if (!result)
  //--- ging nicht - GetLastError() bringt Fehler: 6 ---

Vielleicht hilft ja der Fehlercode aber ich wusste nicht wo ich da nachschauen soll.

M.f.G. Erik
 
Hmm, Fehlercode 6 bedeutet "Handle ist ungültig".

Ist vielleicht das Handle da schon mit CloseHandle bearbeitet worden?
Vielleicht sinds auch die Zugriffsrechte.

Im Visual Studio ist unter Extras->Fehlersuche ein lustiges Tool, da kannst du die Fehlercodes reinstecken und erhältst eine Klartext-Beschreibung.
 
Das Tool ist genial - muss ich mir merken.
Was den Thread angeht so ist das ein bischen komisch.
Ich hab den 100 pro nicht mit CloseHandle() versucht zu scliessen (was im übrigen auch nicht geht)
Die Funktion schreibt, während sie läuft, ständig Daten in ein TreeCtrl - woran man ja sieht, dass sie läuft.

Das einzige was ich mal ausprobiert habe und was auch geklappt hat, war das brachiale schliessen mit "TerminateThread()" - das ging - war aber nur ein Test.

Ungültiger Handle - ich poste mal die Zeile wo ich den her hab:

DWORD id=0;

if (conf.thread_config.pThread == NULL)
conf.thread_config.pThread = CreateThread( NULL, 0, RunSearchThread, (void*)&conf.thread_config, 0, &id);
 
Echt schräg.
Ich erstelle meinen Thread genauso, und SuspendThread/ResumeThread machen das alles einwandfrei.

Das CloseHandle brauchst du nur, wenn der Thread durch ist. Dann gibst du damit die Resourcen für das Handle selbst frei.
 
Bei nem Kumpel klappt das ebenfalls - und der macht auch nichts anderes.
Da kann es ja eigentlich nur irgendeine Nachlässigkeit von mir sein - meisstens irgendsowas banales wie ein Semikolion zu viel oder so. ^_________^°
Soll ich mal die Deklarationen und/oder Definitionen der involvierten Funktionen posten ?
 
Hier die Funktion, welche der ChreateThread als Parameter übergeben wird :

Code:
Deklaration:
static DWORD WINAPI RunSearchThread(LPVOID threat_config);

Definition:
DWORD WINAPI CFindImagesDlg::RunSearchThread(LPVOID config)
{
	//--- Gesichtskontrolle - das ist nur für coole Zeiger ----------------------------------------
	if (config == NULL)
		return FALSE;

	//--- Zeiger zu den Variablen und Klassen bekommen --------------------------------------------
	EINSTELLUNGEN *conf = (EINSTELLUNGEN *)config;
	SEARCH_THREAD_CONFIG *tconf = &conf->thread_config;
	CFindImagesDlg *pWnd = (CFindImagesDlg*)conf->pWnd;
    
	//--- Starten der Suchfunktion ----------------------------------------------------------------
    pWnd->SearchURLsRecurse(tconf->start_url, tconf->visited_list, tconf->iTiefe, tconf->pItem, tconf->pTree, conf);

	//--- den in StartDefaultSearch() reservierten CString wieder freigeben -----------------------
	delete tconf->visited_list;

	//--- Fertig mit Suchen - CSearchThreadDlg aktualisieren --------------------------------------
	pWnd->m_search_thread.SetStatus( THREAD_IDLE );

	//--- Thread ist fertig - Zeiger auf NULL zurücksetzten ---------------------------------------
	conf->thread_config.pThread = NULL;

	return TRUE;
}

Hier ist der Aufruf von CreateThread(...)

Code:
DWORD id=0;
HANDLE handle = NULL;


//--- conf.threat_config.pThread wird in RunSearchThread auf NULL zurück gesetzt --------------
if (conf.thread_config.pThread != NULL)
	Alert("Bitte warten, bis die aktuelle Suche beendet wurde.\t","Suche bereits aktiv", MB_USERICON, MB_OK, IDI_SEARCH, this);
else
	//--- alte Variante --- handle = CreateThread( NULL, 0, RunSearchThread, (void*)&conf.thread_config, 0, &id);
	handle = CreateThread( NULL, 0, RunSearchThread, (void*)&conf, 0, &id);

conf.thread_config.pThread = handle;
 
Sieht alles sauber aus, ich hab das nochmal ausprobiert mit einer rekursiven Funktion und es klappt einwandfrei.
Setz doch mal einen Breakpoint vor deinen SuspendThread-Aufruf und prüfe da, ob das Thread-Handle auch den richtigen Wert hat. Vielleicht wird es irgendwo zwischendrin versehentlich zersägt?

Übrigens, in deiner Thread-Funktion, bevor du das Handle auf NULL setzt, mach da ein CloseHandle drauf. Das tut dem Thread selber nichts, aber Windows hat da an dem Handle ein paar Resourcen dran, die werden dadurch freigegeben.
 

Neue Beiträge

Zurück