Click to See Complete Forum and Search --> : Thread question


egarcia8484
March 22nd, 2006, 02:10 PM
I have a thread question.
I have two functions:
- StartCapturingThread //creates a thread, will be the only thread
- StopCapturingThread // tries to kill this same thread

Here is the Stop code...

void StopCapturingThread()
{
DWORD ret;

g_isDying = 1;
Sleep(10);

ret = WaitForSingleObject(hThread, 5000);

if (ret == WAIT_OBJECT_0) {
CloseHandle(hThread);
hThread = NULL;
}
else {
//......
}
}

I also have a ThreadProc were I do some tasks.

DWORD WINAPI ThreadProc(void * parg)
{
while (!g_isDying) {
// tasks

if (ret != SUCCESS) {
// Error
return -1;
}

}

//tasks...
return 0;
}

My question is: If there is some error in the ThreadProcedure and I have to return from it, how do I close the Thread handle?
When the ThreadProc exits , does this implies that the handle will be =0 or thats something I must do before exiting the proc?

Please help me, since I don't have much threadsss knowledge!!!

wildfrog
March 22nd, 2006, 02:30 PM
If there is some error in the ThreadProcedure and I have to return from it, how do I close the Thread handle?You should close your thread handle when you don't need it any more (if not there will be a resource leak in your application). Where you should close it depends on your design...

When the ThreadProc exits , does this implies that the handle will be =0 or thats something I must do before exiting the proc?
Same as above, you'll have to do that yourself. In fact, if you don't need the handle at all, you can call CloseHandle right away. The thread will run anyway.

- petter

NoHero
March 22nd, 2006, 03:11 PM
[ Moved Thread ]

Vanaj
March 27th, 2006, 07:18 PM
I have a thread question.
I have two functions:
- StartCapturingThread //creates a thread, will be the only thread
- StopCapturingThread // tries to kill this same thread

My question is: If there is some error in the ThreadProcedure and I have to return from it, how do I close the Thread handle?
When the ThreadProc exits , does this implies that the handle will be =0 or thats something I must do before exiting the proc?

Please help me, since I don't have much threadsss knowledge!!!

Just a suggestion...if you use AfxBeginThread() it will return a pointer to a CWinThread Object, then you can set the "m_bAutoDelete" within the CWinThread Object to TRUE and it(thread object) will be deleted upon exit. You should also use the "AfxEndThread( UINT nExitCode );" to exit from a thread created with AfxBeginThread()...

Something like this....

hMyTimer = AfxBeginThread(TimerThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if(!hMyTimer)
{
char szError[128] = {0};
DWORD dwLastError = 0;

memset(szError, (char)NULL, sizeof(szError));
dwLastError = GetLastError();
sprintf(szError, "ERROR Code = %d", dwLastError);
MessageBox("Unable To Start Timer Thread", szError, MB_OK|MB_ICONHAND);
}
else
{
m_bRun = TRUE;
m_bTimerRunning = FALSE;
hMyTimer->m_bAutoDelete = TRUE;

GetSystemInfo(&sSystemInfo);
if(sSystemInfo.dwNumberOfProcessors > 1)
{
SetThreadIdealProcessor(hMyTimer->m_hThread,(DWORD)(sSystemInfo.dwNumberOfProcessors-1));
}
hMyTimer->ResumeThread();
}


Hope this helps a little...

egarcia8484
March 28th, 2006, 09:43 AM
Mmm.. I am using API Thread Functions (not MFC). I still don´t know if I am doing it the right way... at least its working just fine; without any resource leakin'.

Thanks anyway. :D

kirants
April 4th, 2006, 12:38 PM
As suggested, in your StartCapturing thread, you can right away call CloseHandle with the value returned by CreateThread or _beginthread

egarcia8484
April 4th, 2006, 04:26 PM
What for?

Arjay
April 5th, 2006, 11:39 AM
What for?If you don't use the thread handle, the what for is to close it so you don't have a handle resource leak. Does this matter? Maybe not (other than being a bit sloppy), but if you create and use many threads, and your app is running for a long time, then eventually you will exhaust system resources (because the system thinks you are still using the unclosed thread handle).

To determine if you have a resource leak, you can use task manager to view the memory usage and thread and handle count. If counts and usage trend up, you know you have a resource leak (even if the app appears to run fine).

Btw, another approach to threading is to wrap your thread creation/management routines into a class, and in the class destructor you clean up by closing any handles, freeing memory, etc.


Arjay

egarcia8484
April 5th, 2006, 02:21 PM
I dont want to be rude but I've already told I don't have any resource leaking. Besides, in my DLL (I launch the thread from a DLL) I only allow one thread of this kind, and the only point where this resource leaking could be is in the StopCapturingtThread function. I appreciate your help, but my only question is if I am doing it right in the code I've posted.
The code has been working for some time now (couple of months) and it works fine; but I would like to know if it is "nicely coded" or something (just using Windows API)...

Thanks.... P-)

Arjay
April 6th, 2006, 12:01 AM
I dont want to be rude but I've already told I don't have any resource leaking. Besides, in my DLL (I launch the thread from a DLL) I only allow one thread of this kind, and the only point where this resource leaking could be is in the StopCapturingtThread function. I appreciate your help, but my only question is if I am doing it right in the code I've posted.
The code has been working for some time now (couple of months) and it works fine; but I would like to know if it is "nicely coded" or something (just using Windows API)...

Thanks.... P-)As you mentioned, you have a particularly controlled environment, but why not code it up so that handle always get's closed no matter what (regardless of whether the StopCapturingThread gets called)?

With that said, I have two suggestions:

Use a class to ensure the handle gets closed in the dtor
Use an event to signal when to exit the thread rather than using the global variable (if this variable is anything other than a bool, you have a potential for trouble already).

egarcia8484
April 7th, 2006, 02:13 PM
You may be right; however I think the code is more or less well written. It was the very first time I ever use a thread!!!
Here is the hole Thread.cpp file; I post it because someone could find it
of some use (I don´t think so, but what the hell). Excuse me for the spanish commentaries... (I'm from Rosario, Argentina)



#include "Thread.h"

////////////////////////////////////////////////////////
//// Bandera global: indica si el thread debe morir ////
int g_isDying;
////////////////////////////////////////////////////////

/// Esta variable está en fusion.cpp ///
extern int g_ImageFlags;
//////////////////////////////////////

#define tryToDo(x) try { x; } catch(...) {}

HANDLE hThread = NULL;
LPBYTE ppFrame = NULL;
DWORD threadId = 0;

char _aviFileName[MAX_PATH], _aviData[MAX_PATH];
UINT _x = 0;
UINT _y = 0;
UINT _w = 0;
UINT _h = 0;

DWORD WINAPI ThreadProc(void * parg)
{
int ret;

// Instancio la clase CAviFile (Creo el archivo de grabacion)
ret = CreateAVIFile(_aviFileName,_aviData);
if (ret != SUCCESS) {
CloseHandle(hThread);
hThread = 0;
return -1;
}

ret = DDrawInit(_x, _y, _w, _h);
if (ret != SUCCESS) {
hThread = NULL;
return -1;
}

while (!g_isDying) {

ret = GetFrame(&ppFrame);

if (ret == ERR_TIMEOUT) {
continue;
}
else if (ret == ERR_NOSIGNAL) {
Sleep(50);
continue;
}
else if (ret == SUCCESS) {

tryToDo( ImageTransform(ppFrame,g_ImageFlags) );

DDrawPaint(ppFrame);
// AppendFrame(ppFrame); // levanta un cartel si hay error pero sigue
FreeFrame();
}
else
break;
}

// libero la instancia de la clase CAviFile
CloseAVIFile();
DDrawKill();
CloseHandle(hThread);
hThread = NULL;
return 0;
}

int StartCapturingThread(char *aviFileName, char *data, UINT x, UINT y, UINT w, UINT h)
{
if (hThread) {
// Un thread sigue vivo, y sólo admitimos UN thread vivo
g_isDying = 1;
WaitForSingleObject(hThread, 2000);
}

// Copiamos los argumentos a unas variables globales
strcpy(_aviFileName,aviFileName);
strcpy(_aviData,data);
_x = x;
_y = y;
_w = w;
_h = h;

hThread = CreateThread (
0, // Security attributes
0, // Stack size
ThreadProc,
0,
CREATE_SUSPENDED,
&threadId);

if (!hThread)
//Por alguna razón mística no se pudo hacer el thread
return ERR_THREAD;

// Ahora subimos la prioridad
//SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);

g_isDying = 0;

ResumeThread(hThread);

Sleep(200);

return SUCCESS;
}

void StopCapturingThread()
{
DWORD ret;

// Primero me fijo si hay un thread vivo... sino hay ninguno me voy!
if (!hThread)
return;

g_isDying = 1;
Sleep(10);

ret = WaitForSingleObject(hThread, 5000);

if (ret == WAIT_OBJECT_0) {
CloseHandle(hThread);
hThread = NULL;
}
else {
// Si el thread no puede terminar naturalmente...
// lo tratamos de matar a la fuerza
//TerminateThread(hThread, 0);
}
}