Click to See Complete Forum and Search --> : killing thread
young1
November 11th, 2004, 02:44 PM
I have a program will creating a thread whenever it a MSG related to it occurs. the program will have a lot of these kinds MSG, so do you think it will creat many thread, or just the same one. if is is causing many thread, how could i kill them after using it.
TSYS
November 11th, 2004, 02:49 PM
From your description, I expect it will generate many threads. The alternative is to create a thread, then send the messages to it as they occur.
In any event, the best way to terminate a thread is to somehow - like with a message - notify it to terminate itself.
young1
November 11th, 2004, 02:52 PM
thank you, how to send a msg to it when a event occured?
chi_luci
November 11th, 2004, 02:53 PM
you can kill them only by posting a message WM_CLOSE and handle that message in your thread. The number of threads depends of your needs but I suggest only one thread if you don't have need of so many (because else you might need to do of some syncronisation between threads ). Simply do something like :
UINT threadFunc( LPVOID lp )
{
DWORD dwThreadID = GetCurrentThreadId();//do something with this id.. use it to post messages to this thread
BOOL bRet = FALSE;
MSG msg ;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) ; // Force to make the queue
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
switch( msg.message )
{
case WM_CLOSE:
{
return -1;
}
break;
}
}
return 1;
}
Is able to directly call the thread function? like threadFunc(lp)?
chi_luci
November 11th, 2004, 03:15 PM
I guess you wanted to ask how to start a thread.. :wave:
Use:
AfxBeginThread( threadFunc, (LPVOID)pParam );
//pParam = parameter too pass to the thread at creation time
you cannot directly call this thread function because it must use a queue to process messages..
young1
November 11th, 2004, 03:27 PM
I think I am confused by creating a thread and begin a thread.
UINT threadFunc( LPVOID lp ) will be the definition of the thread. and
AfxBeginThread( threadFunc, (LPVOID)pParam ); will start this thread function. but where, and how is it created, is that UINT threadFunc( LPVOID lp ) will be the thread as well as the definition of the thread? if this is the case, there could be only one thread function, not two similiar thread function occures simousltanously?
chi_luci
November 11th, 2004, 03:36 PM
beginning a thread (AfxBeginThread(..) ) is like opening a program.. The same program can have multiple instances, right? So the threads can be based on the same function but the threads are total separated each from another.. You use their IDs to distinguish between them. (or the pointer to them ).
ex:
CWinThread* pThread1 = AfxBeginThread( threadFunc, NULL );
CWinThread* pThread2 = AfxBeginThread( threadFunc, NULL );
//when you need to send a message to this thread use
pThread1->PostThreadMessage( message1, wparam1, lparam1 );
//or for the second thread:
pThread2->PostThreadMessage( message1, wparam1, lparam1 );
//simple as that!
Thanks a lot, you make it as simple as it could be. however I still has some questions here is, everytime you use AfxBeginThread( threadFunc, NULL );
it will creat or call a threadFunc function right? then in oreder to ptrevent from producing many thread would it be like this
//first check if there is a thread, if there is a thread close it, after close it, call again to start a new thread.
if(pThread1!=NULL)
{ pThread1->PostThreadMessage( WM_CLOSE, 0, 0 );
CWinThread* pThread1 = AfxBeginThread( threadFunc, NULL );
}
else
//if there is not there, just start a new
pThread1->PostThreadMessage( WM_CLOSE, 0, 0 );
young1
November 11th, 2004, 04:25 PM
typo I mean
//first check if there is a thread, if there is a thread close it, after close it, call again to start a new thread.
if(pThread1!=NULL)
{ pThread1->PostThreadMessage( WM_CLOSE, 0, 0 );
CWinThread* pThread1 = AfxBeginThread( threadFunc, NULL );
}
else
//if there is not there, just start a new
CWinThread* pThread1 = AfxBeginThread( threadFunc, NULL );
Andreas Masur
November 11th, 2004, 05:21 PM
[ Moved thread ]
Andreas Masur
November 11th, 2004, 05:28 PM
Well...using the 'WM_CLOSE' message will only work if the thread does have a message queue which is only true for UI threads...
Take a look at the following FAQ (http://www.codeguru.com/forum/showthread.php?t=305166) for an example how to do it with worker threads which is the kind of thread you need here (at least as far as I understood the question)...
chi_luci
November 12th, 2004, 03:16 AM
I thought you want to create only 1 thread for processing..
I thread can process different messages, they are queued and handled 1 by one
for example:
UINT threadFunc( LPVOID lp )
{
DWORD dwThreadID = GetCurrentThreadId();//do something with this id.. use it to post messages to this thread
BOOL bRet = FALSE;
MSG msg ;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); // Force to make the queue
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
switch( msg.message )
{
case WM_CLOSE:
{
return -1;
}
break;
case TM_COPY_FILE:
{
copyFile* cf = (copyFile*)msg.lParam;
CopyFile( cf->szSource, cf->szDest, FALSE );
delete cf;
}
break;
}
return 1;
}
//you can do :
MessageHandler1();
MessageHandler2();
//with no problem.. requests will be qeued and solved one by one
//you don't have to close a thread then create it again ...
// the thread remains active until you explicitly close it (via TerminateThread or posting a close message; that happens because the thread has it's own message queue
What I mean is that you don't have to close the thread after processing a message. That's the model I'm using in all my multi-threaded applications and till now I never had any problems..
if you need a simple sample or some more explanations, please let me know.. :rolleyes:
young1
November 12th, 2004, 09:13 AM
please provide the sample, if you could, Thank you
chi_luci
November 12th, 2004, 11:41 AM
I've created a simple sample which illustrates the usage of threads for performing background operations..
the attachment is a project that copyes the files from a source directory into the destination directory, creating also the destination directory.. Important is to see that after you press the copy button, the files are copyed in background (are queued ) so that the main window does not "freeze". When copying is finished, a message is displayed.. Imagine, for instance that you wanna copy 1GB. If you are doing it inside the main thread, your dialog will "freeze" while copying.. Using a special thread it doesn't. :wave:
young1
November 12th, 2004, 01:24 PM
thanks a lot
young1
November 17th, 2004, 04:38 PM
chi_luci:
THe following is the program that I made accodring to the sample that you provioded. however I am facing several problem
class CView: public CFormView
{
public:
CViewDoc* GetDocument() const;
// Operations
public:
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnInitialUpdate(); // called first time after construct
void CView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
//set downloading progress rang and position
m_progress.SetRange(0,255);
m_progress.SetPos(0);
class CView: public CFormView
{
public:
CViewDoc* GetDocument() const;
// Operations
public:
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnInitialUpdate(); // called first time after construct
void CView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
//set downloading progress rang and position
m_progress.SetRange(0,255);
m_progress.SetPos(0);
case TM_MONITORING:
{
CString a=pParent->m_input2; /*8.*****/
while(pParent->m_input2.GetLength()>0)
pParent->UpdateData(FALSE); /*9.******/
break;
case TM_DOWNLOADING:
{
pParent->UpdateData(FALSE); /*9.******/
}
break;
}//switch
}//while
return 1;
} //end
in Cview I defined CString m_input1, and CSting m_input2 and DWORD m_thread and threadFunc function (see /*1.****-/*4.*****)
I initiated threadFunc in OnInitialUpdate() (see /*5.*****)
I defined threadFunc also
I start call threadFunc by post messgae (see /*8.******)
before posting this message, I debuged and find that m_input2={" 158 158 158 "}; and m_input1="";
however, when I debuge into threadFunc(),
I got m_input2 is empty. I did not know why, and When I go to pParent->UpdateData(False); I also got an error message, a debuge asseration error msg occured. indicating file wincor.cpp line 888.
would you please help me solve the problem
chi_luci
November 18th, 2004, 05:29 PM
if you could put the project zipped up would be more easy. I don't know what exacly says the error (you could post the exact error and the last lines where it appears ).
anyway, hope I found the line which is very clear:
ASSERT((CWnd*)p == this); // must be us
// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.
About that assertion, do not use UpdateData in another thread.
and the CString value - it should not happen. I've created a simple project to test that and it's ok. Probably the value is changing in the window thread before you process the message. you can use some syncronisation between the 2 threads to assure exclusive access.
I don't know exactly what you're trying to do, so can't help you much..
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.