Solved

Call to afxBeginThread blocks till completion of thread Why?

Posted on 1997-06-17
4
453 Views
Last Modified: 2008-03-03

 I am having a problem with afxBeginThread()
 
 Here is relevent code:
 
 struct CThreadInfo
 {
       HANDLE m_hEventStartOperation;
       HANDLE m_hEventKillOperation;
       HANDLE m_hEventOperationKilled;
 };
 
 CmainFrame::CMainFrame()
 {...............
 .
 .
 
 // TODO: Add member initialization code here
 
 // Create Events for image_presenter_thread before Starting it
 
 m_himage_presenter_thread_Start = CreateEvent(NULL, FALSE, FALSE, NULL);
 m_himage_presenter_thread_Kill = CreateEvent(NULL, FALSE, FALSE, NULL);
 m_himage_presenter_thread_Killed = CreateEvent(NULL, FALSE, FALSE, NULL);
 
 // Initialize processing thread parameter structures
 
 m_image_presenter_thread_info.m_hEventStartOperation =
 m_himage_presenter_thread_Start;
 m_image_presenter_thread_info.m_hEventKillOperation =
 m_himage_presenter_thread_Kill;
 m_image_presenter_thread_info.m_hEventOperationKilled =
 m_himage_presenter_thread_Killed;
 
 image_presenter_thread = AfxBeginThread(
                   (AFX_THREADPROC) image_presenter((LPVOID*)
 &m_image_presenter_thread_info),
                   (LPVOID*) &m_image_presenter_thread_info,
                   THREAD_PRIORITY_NORMAL,
                   0,0,NULL);
 .
 .
 .
 SetEvent(m_image_presenter_thread_Start);
 }
 
 UINT CMainFrame::image_presenter(void* pParam)
 {
       CThreadInfo* p_image_presenter_thread_info = (CThreadInfo*) pParam;
 
WaitForSingleObject(p_image_presenter_thread_info->m_hEventStartOperation,
 INFINITE);
 .
 .
 .
 }
 
 WHEN the code executes, AfxBeginThread executes and starts
image_presenter(
 )
 But then, AfxBeginThread DOES NOT RETURN.   Why?
 Of course, image_presenter( ) hangs because
 SetEvent(m_image_presenter_thread_Start)  is never executed
 because of the blocking AfxBeginThread call.
 
 Any help will be greatly appreciated
 
 Thanks
 
0
Comment
Question by:sherwingw
  • 2
  • 2
4 Comments
 

Author Comment

by:sherwingw
ID: 1163964
Edited text of question
0
 
LVL 23

Accepted Solution

by:
chensu earned 140 total points
ID: 1163965
image_presenter should be a static member function of CMainFrame.

image_presenter_thread = ::AfxBeginThread(image_presenter, &m_image_presenter_thread_info);

AfxBeginThread should return after it creates a new CWinThread object, calls its CreateThread function to start executing the thread.
0
 

Author Comment

by:sherwingw
ID: 1163966
chensu:

Declaring image_presenter to be a static member function, rather than just a member function of CMainFrame is not a viable soulution, as it SEVERLY restricts fhe functionality of image presenter.  Static functions only have access to static variables and static functions.  Consequently, if image_presenter is declared static, it can not make a call to any of the non static windows routines!

I tried the static solution, and went through the pain of "static-ing" all called functions .......but ran into a windows call, which was not a static function. So this is not viable.

Any other suggestions?
0
 
LVL 23

Expert Comment

by:chensu
ID: 1163967
You have to use a static function or a global function. The reason is that a member function contains an implicit parameter (the this pointer). For example,

UINT CMainFrame::image_presenter(void* pParam);

is actually

UINT CMainFrame::image_presenter(CMainFrame *pThis, void* pParam);

if it is not a static function. And this prototype does not conform to what AfxBeginThread() requires. It is the implicit this pointer that lets you access the non-static members.

So, you can pass some data that the thread needs into the structure pointed by void* pParam. For example, you can pass the window handle. But, do not pass the this pointer. As Microsoft documentation says, it is dangerous to pass C++ objects from one thread to another, unless the objects are designed to be used in such a manner.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now