I have a Multithreaded code with a reset thread defined as:
bool CTestShellDlg::ResetThreads()
{
//if Main worker thread already finished, Just Reset
if (CheckMainThreadFinished())
{
//reset
}
else
if(KillThreads()) //Go ahead and reset if killing is finished.
{
//reset
}
else
return false; //killing already in progress. gotta wait!
}
And KillThreads() is defined as:
bool CTestShellDlg::KillThreads()
{
//if killing not already in progress
if (!CheckKillEvent())
{
//Signall the killing event
SetEvent(h_KillEvent);
if (WaitMainThreadFinished())
{
//call some deletes
//Reset the kill event back to non-signalled to indicate it's no longer in progress
ResetEvent(h_KillEvent);
return true; //Killing successful
}
else IERROR
}
else
return false; //Killing already in progress
}
With
bool WaitMainThreadFinished(){WaitForSingleObject(m_hDoIt_Thread, INFINITE);...}
bool CheckMainThreadFinished(){WaitForSingleObject(m_hDoIt_Thread, 0);...}
Now, I can Call KillThreads() fine. During this process, I WaitForSingleObject(m_hDoIt_Thread, INFINITE) so I know by the end of it, it's definitely signaled. Now if I try to call ResetThreads(), my WaitForSingleObject(m_hDoIt_Thread, 0) in CheckMainThreadFinished() gives me WAIT_FAILED whereas in my understanding it should be WAIT_OBJECT_0. What could possibly cause that?
What is interesting. Is that if I make two consecutive ResetThreads() calls, I don't get the said return value from CheckMainThreadFinished().
Fixed it!
Used GetLastError() and it turned out the handle for
WaitForSingleObject(m_hDoIt_Thread, 0);
was invalid. The reason for that is By default an MFC thread frees its thread handle and deletes the thread object when it exits. That leaves you with an invalid thread pointer and handle, so this way of checking if the main handle is working will not work and an alternative should be used.
Related
I have a MFC code with multiple threads that all make recursive calls to a subroutine, with different parameters.
In the beginning of the subroutine, I make a call to function CheckKillEvent():
bool CTestShellDlg::CheckKillEvent()
{
DWORD waitS;
waitS = WaitForSingleObject(h_KillEvent, 0);
switch (waitS)
{
case WAIT_OBJECT_0:
return true;
break;
case WAIT_TIMEOUT:
return false;
break;
default:
IERROR
break;
}
}
and return() immediately if CheckKillEvent returns true.
fyi, h_killEvent is initialized as:
h_KillEvent = CreateEvent(NULL, true, false, NULL);
ie, it has a manual reset.
However, these threads seem to take (literally) forever to finish after I set the Kill-event as below:
bool CTestShellDlg::KillThreads()
{
//Signall the killing event
SetEvent(h_KillEvent);
if (WaitForMultipleObjects(,,true,)==...)
{
ResetEvent(h_KillEvent);
return true; //Killing successful
}
else
return false; //Killing failed
}
The question is, is there an issue with calling CheckKillEvent() from multiple threads? Should the WaitForSingleObject() be done inside a critical section or something? Or is it simply my recursive code being bad at recursing back to a point where it no longer calls itself?
As Hans suggested in the comment, the problem was in fact with the message pump being blocked. Always best to assign separate threads for tasks that might take long or might themselves need access to the message pump.
my project is a dialog base and activeX container that have event .
when i call a function of activex and wait to fire it's event (with WaitForSingleObject), the application stops and the event doesn't happen until time-out, after time out it will happen.
void COcxTesDlg::OnBnClickedButton1()
{
hEvent = CreateEvent(NULL, TRUE, FALSE, L"testEvent");
ocxObj.ocxFunction();
DWORD res = ::WaitForSingleObject(hEvent, 10000);
if(res != WAIT_OBJECT_0)
AfxMessageBox(L"Time Out");
else
AfxMessageBox(L"before Time Out");
//--- to do some works after ocx event
//---
}
void COcxTesDlg::ocxEventFunc()
{
SetEvent(hEvent);
}
i always see 'Time Out' MessageBox, but if i don't call the WaitForSingleObject() the ocxEventFunc() happens sooner than 1000ms
i want to do some works after event without waiting a lot of time.
please help me.
Of course it does: you are asking your program to wait, and it waits.
Based on your description of what you are trying to do, your design is fundamentally broken: You are inside a message handler, in your main thread and you call WaitForSingleObject. That suspends execution of that thread, which handles all the user interface - and your program if you have only one thread - until the event is signaled or until the timeout expires.
You should rethink your design. Without knowing more it's not easy to suggest alternatives. One possibility is this:
Make a note of the start time (e.g. call GetTickCountEx and store the result).
Loop while start_time - current_time < timeout value. Inside the loop call WaitForSingleObject with 0 for the timeout. That call will not block and will return immediately: if it returns WAIT_OBJECT_0 then the OCX has completed. If it returns WAIT_TIMEOUT it means the OCX hasn't completed. You can then do whatever work you want.
You already have a function that is called when the event happens. Use it.
void COcxTesDlg::OnBnClickedButton1()
{
ocxObj.ocxFunction();
}
void COcxTesDlg::ocxEventFunc()
{
//--- to do some works after ocx event
//---
}
Is it possible to stop a Thread by its associated QFuture Object ?
Currently i've been starting a video capturing process like this.
this->cameraThreadRepresentation = QtConcurrent::run(this,&MainWindow::startLiveCapturing);
Inside the startLiveCapturing-Method an infinite loop is running that captures images and displays them. So if the user wants to stop that process he should simply press a button and that operation stops.
But it seems that i can not stop this thread by calling the cancel method like this ?
this->cameraThreadRepresentation.cancel();
What i am doing wrong and how can i stop that thread or operation.
From the documentation of QtConcurrent::run:
Note that the QFuture returned by QtConcurrent::run() does not support canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function.
What you could do is have a button press set a boolean flag in your main window and build your infinite loop like this:
_aborted = false;
forever // Qt syntax for "while( 1 )"
{
if( _aborted ) return;
// do your actual work here
}
Why don't you create a boolean flag that you can test inside your capturing loop and when it is set, it jumps out and the thread exits?
Something like:
MainWindow::onCancelClick() // a slot
{
QMutexLocker locker(&cancelMutex);
stopCapturing = true;
}
And then for your threaded function:
MainWindow::startLiveCapturing()
{
forever
{
...
QMutexLocker locker(&cancelMutex);
if (stopCapturing) break;
}
}
as Qt Document said, you can not use cancel() function fir QConcurrent::run() but you can cancel tasks by this answer :
https://stackoverflow.com/a/16729619/14906306
I am learning about threading and multithreading..so i just created a small application in which i will update
the progressbar and a static text using threading.I vl get two inputs from the user, start and end values
for how long the loop should rotate.I have 2threads in my application.
Thread1- to update the progressbar(according to the loop) the static text which will show the count(loop count).
Thread2 - to update the another static text which will just diplay a name
Basically if the user clicks start, the progressbar steps up and at the same time filecount and the name are displayed parallely.
There's is another operation where if the user clicks pause it(thread) has to suspend until the user clicks resume.
The problem is,the above will not work(will not suspend and resume) for both thread..but works for a singlw thread.
Please check the code to get an idea and reply me what can done!
on button click start
void CThreadingEx3Dlg::OnBnClickedStart()
{
m_ProgressBar.SetRange(start,end);
myThread1 = AfxBeginThread((AFX_THREADPROC)MyThreadFunction1,this);
myThread2 = AfxBeginThread((AFX_THREADPROC)MyThreadFunction2,this);
}
thread1
UINT MyThreadFunction1(LPARAM lparam)
{
CThreadingEx3Dlg* pthis = (CThreadingEx3Dlg*)lparam;
for(int intvalue =pthis->start;intvalue<=pthis->end; ++intvalue)
{
pthis->SendMessage(WM_MY_THREAD_MESSAGE1,intvalue);
}
return 0;
}
thread1 function
LRESULT CThreadingEx3Dlg::OnThreadMessage1(WPARAM wparam,LPARAM lparam)
{
int nProgress= (int)wparam;
m_ProgressBar.SetPos(nProgress);
CString strStatus;
strStatus.Format(L"Thread1:Processing item: %d", nProgress);
m_Static.SetWindowText(strStatus);
Sleep(100);
return 0;
}
thread2
UINT MyThreadFunction2(LPARAM lparam)
{
CThreadingEx3Dlg* pthis = (CThreadingEx3Dlg*)lparam;
for(int i =pthis->start;i<=pthis->end;i++)
{
pthis->SendMessage(WM_MY_THREAD_MESSAGE2,i);
}
return 0;
}
thread2 function
LRESULT CThreadingEx3Dlg::OnThreadMessage2(WPARAM wparam,LPARAM lparam)
{
m_Static1.GetDlgItem(IDC_STATIC6);
m_Static1.SetWindowTextW(L"Thread2 Running");
Sleep(100);
m_Static1.SetWindowTextW(L"");
Sleep(100);
return TRUE;
}
void CThreadingEx3Dlg::OnBnClickedPause()
{
// TODO: Add your control notification handler code here
if(!m_Track)
{
m_Track = TRUE;
GetDlgItem(IDCANCEL)->SetWindowTextW(L"Resume");
myThread1->SuspendThread();
WaitForSingleObject(myThread1->m_hThread,INFINITE);
myThread2->SuspendThread();
m_Static.SetWindowTextW(L"Paused..");
}
else
{
m_Track = FALSE;
GetDlgItem(IDCANCEL)->SetWindowTextW(L"Pause");
myThread1->ResumeThread();
myThread2->ResumeThread();
/*myEventHandler.SetEvent();
WaitForSingleObject(myThread1->m_hThread,INFINITE);*/
}
}
I thought I should summarize some of the discussion in the comments into an answer.
In Windows programming, you should never try to manipulate a GUI control from a background thread, as doing so can cause your program to deadlock . This means only the main thread should ever touch elements of the GUI. (Technically, what matters is which thread created the control, but it's not common to create controls in background threads).
This requirement is detailed in Joe Newcomer's article on worker threads (see "Worker Threads and the GUI II: Don't Touch the GUI").
You are using SendMessage in your thread procedures. This causes the appropriate message handler for the target control to be invoked, but in the thread that called SendMessage. In your case, that means the background threads run the message handlers and therefore update the progress bar and label.
The alternative is to use PostMessage. This causes the message to be added to a queue to be processed by the main thread's message loop. When the main thread gets to run, it processes the messages in the order they were added to the queue, calling the message handlers itself. Since the main thread owns the windows, it is safe for it to update the controls.
You should also beware that SuspendThread and ResumeThread are tricky to get right. You might want to read this section of Joe Newcomer's article, which describes some of the dangers.
Tasks like this are often better achieved by using a timer. This is a mechanism for having the operating system notify your program when a particular amount of time has passed. You could implement this with a timer as below:
BEGIN_MESSAGE_MAP(CThreadingEx3Dlg, CDialog)
ON_WM_DESTROY()
ON_WM_TIMER()
END_MESSAGE_MAP()
void CThreadingEx3Dlg::OnTimer(UINT_PTR nTimerID)
{
static int progress = 0;
if (nTimerID == 1)
{
m_ProgressBar.SetPos(progress);
CString strStatus;
strStatus.Format(_T("Processing item: %d"), progress);
m_Static.SetWindowText(strStatus);
progress++;
if (progress > end) // If we've reached the end of the updates.
KillTimer(1);
}
}
BOOL CThreadingEx3Dlg::OnInitDialog()
{
// ... initialize controls, etc, as necessary.
SetTimer(1, 100, 0);
}
void CThreadingEx3Dlg::OnDestroy()
{
KillTimer(1);
}
If you want both updates handled at the same time, they can use the same timer. If they need to happen at different times (such as one at a 100 ms interval and another at a 150 ms interval) then you can call SetTimer twice with different IDs. To pause the action, call KillTimer. To resume it, call SetTimer again.
Multi-threading and message queuing is quite a complex game. When you SendMessage from ThreadA to the same thread then it just calls the message handler. If you do it from ThreadA to another thread (ThreadB) then it gets more complicated. ThreadA then posts a message to the ThreadB's message queue and waits on a signal to say that ThreadB has finished processing the message and sent the return value. This raises an instant problem. If ThreadB is not pumping messages then you have a deadlock as the message in ThreadB's will never get "dispatched". This also raises an EVEN bigger problem. If ThreadB's message needs to send a message to a control created in ThreadA then you have a massive architectural problem. As ThreadA is currently suspended waiting for ThreadB to return and ThreadB is suspended waiting for ThreadA to return. Nothing will happen ... They will both sit suspended.
Thats about it really. Its pretty easy as long as you bear these issues in mind. ie It absoloutely IS possible despite what the others have said.
In general though your threading is pretty pointless because you straight away send a message to the main thread to do some processing. Why bother starting the threads in the first place. You may as well not bother because the threads will just sit there waiting for the main thread to return.
Why do you "WaitForSingleObject" anyway when you suspend the first thread? Why not just suspend them both.
All round, though, you aren't giving enough information about what you are doing to say exactly whats going on. What happens when you click pause, for example?
Windows will not operate properly when more than one thread interacts with the GUI. You'll need to reorganize your program so that does not happen.
I want to create a thread for some db writes that should not block the ui in case the db is not there. For synchronizing with the main thread, I'd like to use windows messages. The main thread sends the data to be written to the writer thread.
Sending is no problem, since CreateThread returns the handle of the newly created thread. I thought about creating a standard windows event loop for processing the messages. But how do I get a window procedure as a target for DispatchMessage without a window?
Standard windows event loop (from MSDN):
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Why windows messages? Because they are fast (windows relies on them) and thread-safe. This case is also special as there is no need for the second thread to read any data. It just has to recieve data, write it to the DB and then wait for the next data to arrive. But that's just what the standard event loop does. GetMessage waits for the data, then the data is processed and everything starts again. There's even a defined signal for terminating the thread that is well understood - WM_QUIT.
Other synchronizing constructs block one of the threads every now and then (critical section, semaphore, mutex). As for the events mentioned in the comment - I don't know them.
It might seem contrary to common sense, but for messages that don't have windows, it's actually better to create a hidden window with your window proc than to manually filter the results of GetMessage() in a message pump.
The fact that you have an HWND means that as long as the right thread has a message pump going, the message is going to get routed somewhere. Consider that many functions, even internal Win32 ones, have their own message pumps (for example MessageBox()). And the code for MessageBox() isn't going to know to invoke your custom code after its GetMessage(), unless there's a window handle and window proc that DispatchMessage() will know about.
By creating a hidden window, you're covered by any message pump running in your thread, even if it isn't written by you.
EDIT: but don't just take my word for it, check these articles from Microsoft's Raymond Chen.
Thread messages are eaten by modal loops
Why do messages posted by PostThreadMessage disappear?
Why isn't there a SendThreadMessage function?
NOTE: Refer this code only when you don't need any sort of UI-related or some COM-related code. Other than such corner cases, this code works correctly: especially good for pure computation-bounded worker thread.
DispathMessage and TranslateMessage are not necessary if the thread is not having a window. So, simply just ignore it. HWND is nothing to do with your scenario. You don't actually need to create any Window at all. Note that that two *Message functions are needed to handle Windows-UI-related message such as WM_KEYDOWN and WM_PAINT.
I also prefer Windows Messages to synchronize and communicate between threads by using PostThreadMessage and GetMessage, or PeekMessage. I wanted to cut and paste from my code, but I'll just briefly sketch the idea.
#define WM_MY_THREAD_MESSAGE_X (WM_USER + 100)
#define WM_MY_THREAD_MESSAGE_Y (WM_USER + 100)
// Worker Thread: No Window in this thread
unsigned int CALLBACK WorkerThread(void* data)
{
// Get the master thread's ID
DWORD master_tid = ...;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
if (msg.message == WM_MY_THREAD_MESSAGE_X)
{
// Do your task
// If you want to response,
PostThreadMessage(master_tid, WM_MY_THREAD_MESSAGE_X, ... ...);
}
//...
if (msg.message == WM_QUIT)
break;
}
}
return 0;
}
// In the Master Thread
//
// Spawn the worker thread
CreateThread( ... WorkerThread ... &worker_tid);
// Send message to worker thread
PostThreadMessage(worker_tid, WM_MY_THREAD_MESSAGE_X, ... ...);
// If you want the worker thread to quit
PostQuitMessage(worker_tid);
// If you want to receive message from the worker thread, it's simple
// You just need to write a message handler for WM_MY_THREAD_MESSAGE_X
LRESULT OnMyThreadMessage(WPARAM, LPARAM)
{
...
}
I'm a bit afraid that this is what you wanted. But, the code, I think, is very easy to understand. In general, a thread is created without having message queue. But, once Window-message related function is called, then the message queue for the thread is initialized. Please note that again no Window is necessary to post/receive Window messages.
You don't need a window procedure in your thread unless the thread has actual windows to manage. Once the thread has called Peek/GetMessage(), it already has the same message that a window procedure would receive, and thus can act on it immediately. Dispatching the message is only necessary when actual windows are involved. It is a good idea to dispatch any messages that you do not care about, in case other objects used by your thread have their own windows internally (ActiveX/COM does, for instance). For example:
while( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0 )
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
switch( msg.message )
{
case ...: // process a message
...
break;
case ...: // process a message
...
break;
default: // everything else
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
}