-
September 22nd, 2004, 03:39 AM
#1
Threading problem...
Hi all!
Please help a threading-newby with the following problem:
I'm writing a piece of MFC code which needs to aquire and plot
data from an external hardware, when an external trigger occurs.
When for some reason there will be no trigger to the hardware, the
application is locked while the hardware driver is waiting to be triggered.
I want the GUI-thread to be free while waiting for the trigger, so that the user
can cancel the data aquisition without having to kill the locked app form the
task-manager.
So I want to put my current code for aquiring and plotting the data inside
a worker thread.
I declared a member function
MyAppDlg::AquisitonThread
with the prototype
UINT AquistionThread(LPVOID pParam);
and put my working code inside AquisitionThread.
when I try to do AfxBeginThread(AquisitionThread,this) I get an error which says
that the first parameter of AfxBeginThread can not be converted from
unsigned int (void *) .
If I declare my controlling function als
static UINT AquistionThread(LPVOID pParam);
the error vanishes, but I get hundreds of errors from the body of AuqistionThread
whenever I touch something which is not also "static".
So I can not start the thread or I can do nothing inside it ????
I've read the FAQ on this, but it does not make clear to me how
to get it working
Thanks for helping a rookie at this,
SeQ
Last edited by sequencer; September 22nd, 2004 at 03:52 AM.
-
September 22nd, 2004, 05:29 AM
#2
Calling Functions from inside working thread...
Hi All!
I' ve learned and understood that I have to declare a member function as
Code:
static UINT ThreadFunc(LPVOID pParam);
to make it valid as a thread controling function because it then has no "this"-pointer and
Code:
AfxBeginThread(ThreadFunc,this);
will compile. Fine. When I start programming inside ThreadFunc using standard
library functions, I get errors saying that I'm not allowed calling something non-static
from inside ThreadFunc. In sample codes I see people do this all the time, and it
compiles? How can I make the thread do something then (except writing everything inside from scratch) ?
Please help,
SeQ
-
September 22nd, 2004, 05:35 AM
#3
Re: Calling Functions from inside working thread...
-
September 22nd, 2004, 05:44 AM
#4
Re: Calling Functions from inside working thread...
Originally Posted by sequencer
When I start programming inside ThreadFunc using standard
library functions, I get errors saying that I'm not allowed calling something non-static from inside ThreadFunc.
Since the standard library functions are not members of your class, there shouldn't be any problem in calling them. Can you post the code and the errors you are getting?
The static vs. nonstatic issue only comes into play when you want to access nonstatic member functions or variables of your class - that's where you need to take the LPVOID parameter you get passed into your thread function and cast it back to an "artificial this pointer" (I usually name it pThis) and use that to access nonstatic members. And if you want to avoid changing too much existing code (by adding pThis-> in front of every member you are accessing): Just write a second thread function as a nonstatic member function, and do all your work in there. In the static thread function, you just call that function with pThis->YourActualThreadFunction().
The only thing to watch out for is when you want to access certain MFC objects from within the thread - but that's covered in the article to which Alin posted the link.
-
September 22nd, 2004, 05:58 AM
#5
Re: Threading problem...
I would suggest you to change your code a bit more, for having a good control over your worker thread. In this example the thread takes a CWnd* instance as a parameter. Use this CWnd pointer only to access some custom attributes from the worker thread, or else pass some other "safe" data to CreateThread().
Class declaration (*.h):
Code:
class CWorkerThread : public CWinThread
{
public:
DECLARE_DYNAMIC(CWorkerThread)
CWorkerThread();
// Attributes
public:
CWnd * m_pWndTarget;
HANDLE m_hEventKill;
HANDLE m_hEventDead;
// Operations
public:
BOOL CreateThread(CWnd * pWndTarget);
void KillThread();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWorkerThread)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CWorkerThread();
virtual void Delete();
protected:
virtual BOOL InitInstance();
virtual int ExitInstance();
virtual void SingleStep();
// Generated message map functions
//{{AFX_MSG(CWorkerThread)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Class implementation (*.cpp):
Code:
BOOL PeekAndPump()
{
static MSG msg;
while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
if (!AfxGetApp()->PumpMessage()) {
::PostQuitMessage(0);
return FALSE;
}
}
return TRUE;
}
IMPLEMENT_DYNAMIC(CWorkerThread, CWinThread)
BEGIN_MESSAGE_MAP(CWorkerThread, CWinThread)
//{{AFX_MSG_MAP(CWorkerThread)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CWorkerThread::CWorkerThread()
: m_pWndTarget(NULL)
{
}
BOOL CWorkerThread::CreateThread(CWnd * pWndTarget)
{
m_bAutoDelete = FALSE;
// kill event starts out in the signaled state
m_hEventKill = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventDead = CreateEvent(NULL, TRUE, FALSE, NULL);
m_pWndTarget = pWndTarget;
ASSERT_VALID( m_pWndTarget );
ASSERT( m_pWndTarget->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow(m_pWndTarget->GetSafeHwnd()) );
if ( !CWinThread::CreateThread(CREATE_SUSPENDED) )
{
TRACE0("Failed to create thread\n"); return FALSE;
}
// choose your own priority of this thread... I prefer IDLE
VERIFY(CWinThread::SetThreadPriority(THREAD_PRIORITY_IDLE));
CWinThread::ResumeThread();
return TRUE;
}
BOOL CWorkerThread::InitInstance()
{
;// any thread setup can be here
// loop but check for kill notification
while (WaitForSingleObject(m_hEventKill, 0) == WAIT_TIMEOUT)
SingleStep();
;// any thread cleanup can be here
// avoid entering standard message loop by returning FALSE
return FALSE;
}
void CWorkerThread::SingleStep()
{
if (PeekAndPump())
{
;// one step implementation of the worker thread
/*
when last step finishes, the thread can end itself
by executing these 2 lines of code:
VERIFY(SetEvent(m_hEventKill));
return;
*/
}
}
int CWorkerThread::ExitInstance()
{
// default exit code indicating no error should be 0
return 0;
}
void CWorkerThread::Delete()
{
// calling the base here won't do anything but it is a good habit
CWinThread::Delete();
// acknowledge receipt of kill notification
VERIFY(SetEvent(m_hEventDead));
}
CWorkerThread::~CWorkerThread()
{
CloseHandle(m_hEventKill);
CloseHandle(m_hEventDead);
}
void CWorkerThread::KillThread()
{
// Note: this function is called in the context of other threads,
// not the thread itself.
// reset the m_hEventKill which signals the thread to shutdown
VERIFY(SetEvent(m_hEventKill));
// allow thread to run at higher priority during kill process
SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
WaitForSingleObject(m_hEventDead, INFINITE);
WaitForSingleObject(m_hThread, INFINITE);
// now delete CWinThread object since no longer necessary
delete this;
}
Sample usage:
Code:
// declare an instance of your worker thread
CWorkerThread * worker;
// whenever you need to start the worker worker thread
worker = new CWorkerThread();
if (!worker->CreateThread((CWnd*)this))
{
//means thread failed to start
delete worker;
worker = NULL;
}
// whenever you need to kill your worker thread before it's time
if (worker)
{
worker->KillThread();
worker = NULL;
}
-
September 22nd, 2004, 06:20 AM
#6
Re: Calling Functions from inside working thread...
Thanks very much so far. This has been helpful. I think I am getting the hang of it slowly...
Thanks,
SeQ
-
September 22nd, 2004, 09:05 AM
#7
Re: Calling Functions from inside working thread...
Last edited by Andreas Masur; September 22nd, 2004 at 09:09 AM.
-
September 22nd, 2004, 09:25 AM
#8
Re: Threading problem...
Use CallBack OBJECTS, not raw functions!!!! There have been many good discussions written about them here on CodeGuru!!!!!
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
September 22nd, 2004, 09:30 AM
#9
-
September 22nd, 2004, 09:32 AM
#10
Re: Threading problem...
in the beginning of my experience with multi-threading programmation i used to use AfxBeginThread() to launch threads but i got so many probs (synchronisation prob , the fact that we ain't able to stop thread from the outside of the thread ...) i serached for an other solution and i found the solution in code guru with a very useful class named CMyThread it's so easy to use and it allows you to control at 100% ur threads
We are the memories we let to other people
Rate if i helped
-
September 22nd, 2004, 12:39 PM
#11
Re: Threading problem...
Originally Posted by Black_Daimond
in the beginning of my experience with multi-threading programmation i used to use AfxBeginThread() to launch threads but i got so many probs (synchronisation prob , the fact that we ain't able to stop thread from the outside of the thread ...) i serached for an other solution and i found the solution in code guru with a very useful class named CMyThread it's so easy to use and it allows you to control at 100% ur threads
Well...I never experienced any problems with 'AfxBeginThread()'...whether a thread can be stopped from outside does not depend on the function used to create it...
-
September 22nd, 2004, 01:13 PM
#12
Re: Threading problem...
i haven't well explained my post ,the prob doesn't come from AfxBeginThread() but from the thread .with AfxBeginThread we launch the thread but we must implement ourselves the way to control it ...
We are the memories we let to other people
Rate if i helped
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|