CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Nov 2001
    Posts
    20

    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.

  2. #2
    Join Date
    Nov 2001
    Posts
    20

    Unhappy 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

  3. #3
    Join Date
    Feb 2002
    Posts
    3,788

    Re: Calling Functions from inside working thread...


  4. #4
    Join Date
    Sep 2002
    Location
    14° 39'19.65"N / 121° 1'44.34"E
    Posts
    9,815

    Re: Calling Functions from inside working thread...

    Quote 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.

  5. #5
    Join Date
    Aug 2004
    Location
    Bucharest, Romania... sometimes
    Posts
    1,039

    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;
    	}
    Bogdan Apostol
    ESRI Developer Network

    Compilers demystified - Function pointers in Visual Basic 6.0
    Enables the use of function pointers in VB6 and shows how to embed native code in a VB application.

    Customize your R2H
    The unofficial board dedicated to ASUS R2H UMPC owners.

  6. #6
    Join Date
    Nov 2001
    Posts
    20

    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

  7. #7
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Calling Functions from inside working thread...

    [ Merged threads ]
    Last edited by Andreas Masur; September 22nd, 2004 at 09:09 AM.

  8. #8
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    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

  9. #9
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Threading problem...

    [ Moved thread ]

  10. #10
    Join Date
    Mar 2003
    Location
    Morocco
    Posts
    257

    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

  11. #11
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Threading problem...

    Quote 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...

  12. #12
    Join Date
    Mar 2003
    Location
    Morocco
    Posts
    257

    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
  •  





Click Here to Expand Forum to Full Width

Featured