Thread exit problem
-
Hello, I have an application that has to start a new thread. In this thread I acquire and I calculate data. So, when I exit the program, I terminate the Thread but the thread doesn't exit! Here is the code: Starting the Thread:
CMyClass::Enable() //To start the Thread
{
//... do some stuff here
fEnabled = 1;
DWORD ThreadID;
m_hNewThread = CreateThread(
NULL, //No Security
0, //Same Stacksize
MyClassThreadProc, //Thread Proc
this, //Adress of my class
0, //start at once
&ThreadID);
}Thread Proc function:
DWORD WINAPI MyClassThreadProc( LPVOID pParam )
{
CMyClass* pObject = (CMyClass*)pParam;if (pObject == NULL) return -1; // illegal parameter // do something with 'pObject' pObject->ServiceHandler(); return 0; // thread completed successfully
}
Idle function:
void CMyClass::ServiceHandler()
{
while (fEnabled)
{
//Do stuf here: read and calculate data !
}
}When I want to exit the Thread, I call this function:
void CMyClass::Disable()
{
if (!fEnabled)
return;DWORD ExitCode; fEnabled=0; //Wait for ServiceThread GetExitCodeThread(m\_hNewThread,&ExitCode); while(ExitCode == STILL\_ACTIVE) GetExitCodeThread(m\_hNewThread,&ExitCode); //Close Serial Port WRS232::Close(); return;
}
But that doesn't work !! The while loop in the Disable function never ends !!! I have not this problem when I set a breakpoint in this loop ! Thanks for help !!
-
Hello, I have an application that has to start a new thread. In this thread I acquire and I calculate data. So, when I exit the program, I terminate the Thread but the thread doesn't exit! Here is the code: Starting the Thread:
CMyClass::Enable() //To start the Thread
{
//... do some stuff here
fEnabled = 1;
DWORD ThreadID;
m_hNewThread = CreateThread(
NULL, //No Security
0, //Same Stacksize
MyClassThreadProc, //Thread Proc
this, //Adress of my class
0, //start at once
&ThreadID);
}Thread Proc function:
DWORD WINAPI MyClassThreadProc( LPVOID pParam )
{
CMyClass* pObject = (CMyClass*)pParam;if (pObject == NULL) return -1; // illegal parameter // do something with 'pObject' pObject->ServiceHandler(); return 0; // thread completed successfully
}
Idle function:
void CMyClass::ServiceHandler()
{
while (fEnabled)
{
//Do stuf here: read and calculate data !
}
}When I want to exit the Thread, I call this function:
void CMyClass::Disable()
{
if (!fEnabled)
return;DWORD ExitCode; fEnabled=0; //Wait for ServiceThread GetExitCodeThread(m\_hNewThread,&ExitCode); while(ExitCode == STILL\_ACTIVE) GetExitCodeThread(m\_hNewThread,&ExitCode); //Close Serial Port WRS232::Close(); return;
}
But that doesn't work !! The while loop in the Disable function never ends !!! I have not this problem when I set a breakpoint in this loop ! Thanks for help !!
Have you added the
volatile
keyword to thefEnable
flag? That's needed, otherwise the compiler will remove thewhile (fEnabled)
statement during optimizing the code. Daniel ;) --------------------------- Never change a running system! -
Have you added the
volatile
keyword to thefEnable
flag? That's needed, otherwise the compiler will remove thewhile (fEnabled)
statement during optimizing the code. Daniel ;) --------------------------- Never change a running system!Hello! Thanks for reply . I forgot the volatile keyword ! But, it doesn't work with it neither :(! When I exit my application, the Pocket PC goes much much more slowly (the thread is still in use)! Any idea?
-
Hello! Thanks for reply . I forgot the volatile keyword ! But, it doesn't work with it neither :(! When I exit my application, the Pocket PC goes much much more slowly (the thread is still in use)! Any idea?
Take a look at the following code that I use in some of my projects. I create a thread at program start and terminate it when the user close the dialog.
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();// TODO: Add extra initialization here m\_bRunning = TRUE; // Create the thread and start it m\_pSendDataThread = AfxBeginThread(SendData, this, THREAD\_PRIORITY\_NORMAL, 0, // stack size CREATE\_SUSPENDED); ASSERT\_VALID(m\_pSendDataThread); m\_pSendDataThread->m\_bAutoDelete = FALSE; m\_pSendDataThread->ResumeThread(); // start the thread return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
}
UINT CMyDlg::SendData(LPVOID pParam)
{
CMyDlg* pDialog = reinterpret_cast(pParam);
ASSERT(pDialog);if (pDialog) pDialog->SendData(); // send the data to the server (host) return 0;
}
void CMyDlg::SendData()
{
while (m_bRunning)
{
// do something
}
}void CMyDlg::OnDestroy()
{
CDialog::OnDestroy();// TODO: Add your message handler code here m\_bRunning = FALSE; // Wait until the thread is terminated WaitForSingleObject(m\_pSendDataThread->m\_hThread, INFINITE); delete m\_pSendDataThread;
}
Daniel ;) --------------------------- Never change a running system!
-
Take a look at the following code that I use in some of my projects. I create a thread at program start and terminate it when the user close the dialog.
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();// TODO: Add extra initialization here m\_bRunning = TRUE; // Create the thread and start it m\_pSendDataThread = AfxBeginThread(SendData, this, THREAD\_PRIORITY\_NORMAL, 0, // stack size CREATE\_SUSPENDED); ASSERT\_VALID(m\_pSendDataThread); m\_pSendDataThread->m\_bAutoDelete = FALSE; m\_pSendDataThread->ResumeThread(); // start the thread return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
}
UINT CMyDlg::SendData(LPVOID pParam)
{
CMyDlg* pDialog = reinterpret_cast(pParam);
ASSERT(pDialog);if (pDialog) pDialog->SendData(); // send the data to the server (host) return 0;
}
void CMyDlg::SendData()
{
while (m_bRunning)
{
// do something
}
}void CMyDlg::OnDestroy()
{
CDialog::OnDestroy();// TODO: Add your message handler code here m\_bRunning = FALSE; // Wait until the thread is terminated WaitForSingleObject(m\_pSendDataThread->m\_hThread, INFINITE); delete m\_pSendDataThread;
}
Daniel ;) --------------------------- Never change a running system!
Ok, that works fine with AfxBeginThread and WaitForSingleObject (I just replaced these functions). Don't know why it didn't work with my method! Thanks a lot for your help ;)