Why does my multithread application hang? - c++

I have code that creates and starts a thread:
CWinThread *m_pThread;
m_pThread = AfxBeginThread(StartThread, m_pObj, THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED, 0);
m_pThread->m_bAutoDelete = FALSE;
m_pThread->ResumeThread();
This is my function. It waits to finish this thread because I want start new thread:
void Some()
{
m_pObj->bRefresh = true;
DWORD dw = ::WaitForSingleObject(m_pThread->m_hThread, INFINITE);//hangs and doesn't move anywhere
}
But returning from my thread is fine.
Please help me find what I did wrong?
UINT StartThread(LPVOID lpParam)
{
Obj *pObj = (Obj*)lpParam;
while(!pObj->Refresh)
{}
return 0;
}

The main problem was that I couldn't return from loop, and that's why my thread hangs
thanks a lot for replaying

Related

When I close a thread created by a dll plugin, the whole program closes

I need a thread timer for a plugin. The code executes well. The problem is when closing the plugin must close the created thread.
When the thread closes, the whole program closes. How can I close the safe plugin without closing the whole parent program.
class MYCLASS {
public:
.............
static DWORD WINAPI threadProc(LPVOID innerThread) {
MYCLASS *pThis = reinterpret_cast<MYCLASS*>(innerThread);
if (pThis->process_on) {
// EXECUTE
}
Sleep(100);
}
exit(0);
}
MYCLASS::OnClose();
.............
private:
bool process_on;
HANDLE hThread; DWORD ThreadID;
.............
hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadProc, (void*)this, 0, &ThreadID);
..............
void MYCLASS::OnClose() {
thread_process=false;
DWORD dwExitCode;
GetExitCodeThread(hThread, &dwExitCode);
ExitThread(dwExitCode);
}

Call a function from a thread and RS 232

I am programming in Visual Studio 2008 in console application. I am working with a display that is communicated by Rs 232.
I have a thread that counts from 0 to 10 seconds. When reaches 10 I want to turn off the displays backlight. For that I have a function that is called from the thread. The called from the thread is well because I know that the code of the function is executed.
But code of turning the backlight off does not work when the function is called from the thread and it works the it is called from another place. Any ideas?
Thanks.
void FunctionBacklightoff(HANDLE portHandle,DWORD bytesTransmitted)
{
cout << "backoff";
WriteFile(portHandle, backlight_off , 4, &bytesTransmitted, NULL);//does not work when
//it is called from the thread. It works when it is called from wmain()
}
DWORD WINAPI solo_thread(void* arg)
{
int Counter = 0;
printf( "In second thread...\n" );
while ( true )
{
if(Counter<10)
{
Counter++;
Sleep(1000);
}
else
{
printf( "Han pasado 10 segundos; Counter:-> %d\n", Counter );
FunctionBacklightoff(portHandle,bytesTransmitted);//from here doesnt work
Counter = 0;
}
}
return 0;
}
int wmain(void)
{
hThread =CreateThread(NULL, 0, solo_thread,NULL ,0, NULL);
//inicialize rs232 communications...
retVal = PortOpen(&portHandle, 115200);
if (!retVal)
{
printf("Could not open CoM port");
getchar();
}
else
{
printf("CoM port opened successfully");
retVal = FALSE;
}
FunctionBacklightoff(portHandle,bytesTransmitted);//from here works
}
How portHandle is declared? Looks like it's static field so thread could simply not get change that happen after it's creation. To be sure you could mark portHandle as volatile or change the order of operations:
//Open port so we will be sure that postHandle is populated before thread starts.
retVal = PortOpen(&portHandle, 115200);
hThread = CreateThread(NULL, 0, solo_thread,NULL ,0, NULL);
Also you have a BUG that your wmain will exit before thread being executed. To fix that you should place following code right before wmain last bracket:
WaitForSingleObject(hThread, INFINITE);
Note that because your thread have while(true) without break condition it will run forever and each 10 seconds will switch off backlight. If this was not intentional add a break into else.

Why semaphore is released but WaitForSingleObject() still stuck?

UPDATE: I found that the semaphore they are releasing is not the semaphore the monitor thread is waiting! I used cout<<ready to find the semaphore the threads are releasing is 00000394, which is not the handle of the semaphore the monitor thread is waiting for. What is the possible reason for this problem? Thank you!
I am new to multithread programming in Windows. Today when I'm writing my online game server, I try to use semaphores in Windows. It is written based on IOCP so that every message is handled in a separate thread. A game consists 4 players.
What I expect it to do is: when receiving a message, a new thread starts and release a ready. There is a monitor thread waiting for 4 ready, and then releases 4 all_ready. Each thread waits one all_ready and goes on.
The code is here:
CGameHost is a manager for a 4-player game.
CGameHost::CGameHost(void)
{
init_times=0;
ready = CreateSemaphore(NULL, 0, 4, NULL);
read = CreateSemaphore(NULL, 0, 4, NULL);
all_ready = CreateSemaphore(NULL, 0, 4, NULL);
all_read = CreateSemaphore(NULL, 0, 4, NULL);
monitor_thread = (HANDLE)_beginthreadex(NULL, 0, Monitor, (LPVOID)this, NULL, 0);
}
unsigned __stdcall CGameHost::Monitor( LPVOID p ) // a static function
{
CGameHost *nowp = (CGameHost *)p;
while(true)
{
int i;
for(i=1;i<=MAX_PLAYER;i++)
{
WaitForSingleObject(nowp->ready, INFINITE);//stuck here
cout<<"Get Ready!"<<endl; // This is not outputed, which means it stucks in the last row.
}
for(i=1;i<=MAX_PLAYER;i++)
{
ReleaseSemaphore(nowp->all_ready, 1, NULL);
}
for(i=1; i<=MAX_PLAYER; i++)
{
WaitForSingleObject(nowp->read, INFINITE);
}
for(i=1; i<=MAX_PLAYER;i++)
{
ReleaseSemaphore(nowp->all_read, 1, NULL);
}
}
return 0;
}
void CGameHost::ReleaseReady()
{
ReleaseSemaphore(ready, 1, NULL);
}
void CGameHost::WaitAllReady()
{
WaitForSingleObject(all_ready, INFINITE);
}
void CGameHost::ReleaseRead()
{
ReleaseSemaphore(read, 1, NULL);
}
void CGameHost::WaitAllRead()
{
WaitForSingleObject(all_read, INFINITE);
}
DataProcess::Game is the message handler for incoming game messages.
CMessage Dataprocess::Game( CMessage* recv_msg )
{
CMessage ret;
int now_roomnum = recv_msg->para1;
int now_playernum = recv_msg->para2;
if(true)
{
cout<<"Received Game Message: "<<endl;
cout<<"type2 = "<<recv_msg->type2;
cout<<" player_num = "<<now_playernum<<" msg= "<<recv_msg->msg<<endl;
}
if(recv_msg->type2 == MSG_GAME_OPERATION)
{
ret.type1 = MSG_GAME;
ret.type2 = MSG_GAME_OPERATION;
cout<<"Entered from "<<now_playernum<<endl;
game_host[now_roomnum].SetMessage(now_playernum, recv_msg->msg);
game_host[now_roomnum].ReleaseReady();
cout<<"Released Ready from "<<now_playernum<<endl;//this is shown
game_host[now_roomnum].WaitAllReady();//stuck here
cout<<"AllReady from"<<now_playernum<<endl;//not shown
}
return ret;
}
Your reply will be of great help for a beginner of Windows multithread programmer like me! Thank you!
If I understood your needs, you should probably have something like this..
HANDLE hPlayersReady[4];
HANDLE hAllPlayed;
Create these 5 events, and then on your monitor thread,
do something like this...
while(true)
{
// Wait for all players to move
WaitForMultipleObjects(4, &hPlayersReady, true, INFINITE);
// Process move
...
// Advise players the move was processed...
SetEvent(hAllPlayed);
}
And on your player thread X
while(true)
{
// Make my move
...
// Advise monitor I'm ready
SetEvent(hPlayersReady[X]);
// Wait for ready to do another move
WaitForSingleObject(hAllPlayed);
}
Well, I solved it myself. The reason is that I used CreateSemaphore again after creating the thread, making the player thread visiting different semaphores as the monitor thread... Sorry for my stupidness, and thank you for telling me so much!

Crash when thread is deleted

I am developing an application with MFC.
The UI thread launch a worker thread and stop it when the app is closing. The issue is that the app is crashing each time it tries to delete the thread.
here is the code :
First the thread class and its implementation :
class FileThread : public CWinThread
{
public:
static FileThread* CreateWorkerThread(LPVOID params, UINT priority, UINT flags);
void InitThread();
void StopThread();
inline HANDLE GetStopHandle() const { return m_stopThread; }
inline HANDLE GetWaitHandle() const { return m_waitThread; }
private:
HANDLE m_stopThread;
HANDLE m_waitThread;
FileThread(): m_stopThread(NULL), m_waitThread(NULL) { }
static UINT MyThreadProc(LPVOID pParam);
};
FileThread* FileThread::CreateWorkerThread(LPVOID params, UINT priority, UINT flags)
{
return (FileThread*) AfxBeginThread(FileThread::MyThreadProc, params, priority, 0, flags);
}
void FileThread::InitThread()
{
m_stopThread = CreateEvent(0, TRUE, FALSE, 0);
m_waitThread = CreateEvent(0, TRUE, FALSE, 0);
}
void FileThread::StopThread()
{
::SetEvent(m_stopThread);
::WaitForSingleObject(m_waitThread, INFINITE);
::CloseHandle(m_stopThread);
::CloseHandle(m_waitThread);
}
UINT FileThread::MyThreadProc(LPVOID pParam)
{
ThreadData* pLink = (ThreadData*)pParam;
BOOL continueProcess = TRUE;
int returnCode = EXITCODE_SUCCESS;
while (continueProcess)
{
if(::WaitForSingleObject(pLink->pMe->GetStopHandle(), 0) == WAIT_OBJECT_0)
{
::SetEvent(pLink->pMe->GetWaitHandle());
continueProcess = FALSE;
}
// the thread is looking for some files...
}
delete pLink; // it was allocated from the UI thread
return returnCode;
}
Then, where I start the thread:
ThreadData * td = new ThreadData();
m_myFileThread = FileThread::CreateWorkerThread((LPVOID)td, THREAD_PRIORITY_LOWEST, CREATE_SUSPENDED);
td->pMe = m_myFileThread;
m_myFileThread->m_bAutoDelete = FALSE;
m_myFileThread->InitThread();
m_myFileThread->ResumeThread();
Finally, the stop (and the crash):
DWORD exitCode;
if (m_myFileThread != NULL && GetExitCodeThread(m_myFileThread->m_hThread, &exitCode) && (exitCode == STILL_ACTIVE))
{
m_myFileThread->StopThread();
if(::WaitForSingleObject(m_myFileThread->m_hThread, 5000) == WAIT_TIMEOUT)
{
TerminateThread(m_myFileThread->m_hThread, EXITCODE_ABORT);
}
}
if (m_myFileThread != NULL)
{
delete m_myFileThread; // => CRASH
}
It seems I try to delete something already deleted and end up with a heap corruption. I have try to set the m_bAutoDelete to TRUE and not delete the thread myself by I got the same crash (while the program was trying to call AfxEndThread).
The thread terminate its thread proc and return the exit code.
It looks to me like there is a problem here:
FileThread* FileThread::CreateWorkerThread(LPVOID params, UINT priority,
UINT flags)
{
return (FileThread*) AfxBeginThread(FileThread::MyThreadProc, params,
priority, 0, flags);
}
AfxBeginThread returns a CWinthread*, so just casting this to a derived class of your own does not make it an instance of that derived class. I'm surprised it works at all.
Rather than deriving FileThread from CWinThread, it might be better to hold a CWinthread* member variable inside your wrapper class and expose the thread handle via an accessor if necessary.

Why isn't the mutex being aquired?

I have been looking into all of the different syncronization primitives available in the WinAPI, but have been struggling with what should have been something simple. Why doesn't the following code work?
class MultiThreadedCounter
{
private:
int count; HANDLE hMutex;
public:
void IncrementCounter()
{
if (count == 0)
hMutex = CreateMutex(NULL, TRUE, NULL);
count++;
}
void DecrementCounter()
{
count--;
if (count == 0)
ReleaseMutex(hMutex);
}
void WaitForCounterToReachZero()
{
WaitForSingleObject(hMutex, INFINITE);
CloseHandle(hMutex);
}
};
MultiThreadedCounter extractionsInProgressCounter;
It's definitely getting called in the right order. First, IncrementCounter() is called by the main thread before the async task (here, a thread sleep). Then the main thread calls WaitForCounterToReachZero(). Finally, the background thread calls DecrementCounter() when it has completed its work, which should allow the main thread to proceed.
However, WaitForSingleObject is not waiting. It returns immediately, with WAIT_OBJECT_0. Why is it doing that? It's almost like the mutex was never initially aquired. However, in the call to CreateMutex, I set bInitialOwner to TRUE, which is why I don't understand why it doesn't seem to have been aquired. I guess I have misunderstood something.
Thank you.
EDIT 1:
OK, so to test, I changed IncrementCounter() to:
void IncrementCounter()
{
if (count == 0)
{
hMutex = CreateMutex(NULL, TRUE, NULL);
DWORD var1 = WaitForSingleObject(hMutex, INFINITE);
DWORD var2 = WaitForSingleObject(hMutex, INFINITE);
}
count++;
}
That really, really should have deadlocked it, but no, both calls to WaitForSingleObject returned immediately with var1 and var2 both equal to 0 (which according to the headers is WAIT_OBJECT_0).
The call to CreateMutex can't be working, can it? Yet hMutex gets set to a sensible value and GetLastError() remains at 0. So confused...
EDIT 2: Thank you all for your help. I never got this to work, however, I now realise that I was doing this the wrong way anyway. So I switched everything over to an Event, at which point it worked, then added a few conditionals to deal with out of order increments & decrements, then a critical section to protect the count variable. And it works :)
class MultiThreadedCounter
{
private:
int count; HANDLE hEvent; CRITICAL_SECTION criticalSection;
public:
void IncrementCounter()
{
EnterCriticalSection(&criticalSection);
if (count == 0)
ResetEvent(hEvent);
count++;
LeaveCriticalSection(&criticalSection);
}
void DecrementCounter()
{
EnterCriticalSection(&criticalSection);
if (count > 0)
count--;
if (count == 0)
SetEvent(hEvent);
LeaveCriticalSection(&criticalSection);
}
void WaitForCounterToReachZero()
{
WaitForSingleObject(hEvent, INFINITE);
}
MultiThreadedCounter()
{
hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
InitializeCriticalSection(&criticalSection);
count = 0;
}
~MultiThreadedCounter()
{
CloseHandle(hEvent);
DeleteCriticalSection(&criticalSection);
}
};
You don't show a constructor for MultiThreadedCounter. Without this, there is no place to initialise count to 0, meaning that the first call to IncrementCounter almost certainly won't call CreateMutex
Your constructor should look something like
MultiThreadedCounter()
: count(0)
, hMutex(NULL)
{
}
As an aside, if you need a lock that is used between threads in a single process, you could consider using a critical section instead.