UINT __stdcall CExternal::WorkThread( void * pParam)
{
HRESULT hr;
CTaskBase* pTask;
CComPtr<IHTMLDocument3> spDoc3;
CExternal* pThis = reinterpret_cast<CExternal*>(pParam);
if (pThis == NULL)
return 0;
// Init the com
::CoInitializeEx(0,COINIT_APARTMENTTHREADED);
hr = ::CoGetInterfaceAndReleaseStream(
pThis->m_pStream_,
IID_IHTMLDocument3,
(void**)&spDoc3);
if(FAILED(hr))
return 0;
while (pThis->m_bShutdown_ == 0)
{
if(pThis->m_TaskList_.size())
{
pTask = pThis->m_TaskList_.front();
pThis->m_TaskList_.pop_front();
if(pTask)
{
pTask->doTask(spDoc3); //do my custom task
delete pTask;
}
}
else
{
Sleep(10);
}
}
OutputDebugString(L"start CoUninitialize\n");
::CoUninitialize(); //release com
OutputDebugString(L"end CoUninitialize\n");
return 0;
}
The above the code that let my thread hang, the only output is "start CoUninitialize".
m_hWorker_ = (HANDLE)_beginthreadex(NULL, 0, WorkThread, this, 0, 0);
This code starts my thread, but the thread can't exit safely, so it waits. What the problem with this code?
The problem is not in this code, although it violates core COM requirements. Which says that you should release interface pointers when you no longer use them, calling IUnknown::Release(), and that an apartment-threaded thread must pump a message loop. Especially the message loop is important, you'll get deadlock when the owner thread of a single-threaded object (like a browser) is not pumping.
CoUninitialize() is forced to clean up the interface pointer wrapped by spDoc3 since you didn't do this yourself. It is clear from the code that the owner of the interface pointer actually runs on another thread, something to generally keep in mind since that pretty much defeats the point of starting your own worker thread. Creating your own STA thread doesn't fix this, it is still the wrong thread.
So the proxy needs to context switch to the apartment that owns the browser object. With the hard requirement that this apartment pumps a message loop so that the call can be dispatched on the right thread in order to safely call the Release() function. With very high odds that this thread isn't pumping messages anymore when your program is shutting down. Something you should be able to see in the debugger, locate the owner thread in the Debug + Windows + Threads window and see what it is doing.
Deadlock is the common outcome. The only good way to fix it is to shut down threads in the right order, this one has to shut down before the thread that owns the browser object. Shutting down a multi-threaded program cleanly can be quite difficult when threads have an interdependency like this. The inspiration behind the C++11 std::quick_exit() addition.
Related
This question is about GTK and threads.
You may find it useful if your application crashes, freezes or you want to have a multithreaded GTK application.
Main Loop
In order to understand GTK you must understand 2 concepts.
All contemporary GUIs are single-threaded. They have a thread which processes events from window system (like button, mouse events).
Such a thread is called main event loop or main loop.
GTK is also single threaded and not MT-safe. This means, that you must not call any GTK functions from other threads, as it will lead to undefined behaviour.
As Gtk documentation states,
Like all GUI toolkits, GTK+ uses an event-driven programming model. When the user is doing nothing, GTK+ sits in the “main loop” and waits for input. If the user performs some action - say, a mouse click - then the main loop “wakes up” and delivers an event to GTK+. GTK+ forwards the event to one or more widgets.
Gtk is event-based and asynchronous. It reacts to button clicks not in the exact moment of clicking, but a bit later.
It can be very roughly written like this (don't try this at home):
static list *pollable;
int main_loop (void)
{
while (run)
{
lock_mutex()
event_list = poll (pollable); // check whether there are some events to react to
unlock_mutex()
dispatch (event_list); // react to events.
}
}
void schedule (gpointer function)
{
lock_mutex()
add_to_list (pollable, something);
unlock_mutex()
}
I want a delayed action in my app
For example, hide a tooltip in several seconds or change button text.
Assuming your application is single-threaded, if you call sleep() it will be executed in main loop.
sleep() means, that this particular thread will be suspended for specified amount of seconds. No work will be done.
And if this thread is main thread, GTK will not be able to redraw or react to user interactions. The application freezes.
What you should do is schedule function call. It can be done with g_timeout_add or g_idle_add
In the first case our poll() from snippet above will return this event in several seconds. In the latter case it will be returned when there are no events of higher priority.
static int count;
gboolean change_label (gpointer data)
{
GtkButton *button = data;
gchar *text = g_strdup_printf ("%i seconds left", --count);
if (count == 0)
return G_SOURCE_REMOVE;
return G_SOURCE_CONTINUE;
}
void button_clicked (GtkButton *button)
{
gtk_button_set_label (button, "clicked");
count = 5;
g_timeout_add (1 * G_TIME_SPAN_SECOND, change_label, button);
}
Returning a value from function is very important. If you don't do it, the behaviour is undefined, your task may be called again or removed.
I have a long-running task
Long-running tasks aren't different from calling sleep. While one thread is busy with that task, it can't perform any other tasks, obviously. If that is a GUI thread, it can't redraw interface. That's why you should move all long-running tasks to other threads. There is an exception, though: non-blocking IO, but it's out of topic of my answer.
I have additional threads and my app crashes
As already mentioned, GTK is not MT-safe. You must not call Gtk functions from other threads.
You must schedule execution. g_timeout_add and g_idle_add are MT-safe, unlike other GTK functions.
That callbacks will be executed in main loop. If you have some shared resources between callback and thread you must read/write them atomically or use a mutex.
static int data;
static GMutex mutex;
gboolean change_label (gpointer data)
{
GtkButton *button = data;
int value;
gchar *text;
// retrieve data
g_mutex_lock (&mutex);
value = data;
g_mutex_unlock (&mutex);
// update widget
text = g_strdup_printf ("Current data value: %i", value);
return G_SOURCE_REMOVE;
}
gpointer thread_func (gpointer data)
{
GtkButton *button = data;
while (TRUE)
{
sleep (rand_time);
g_mutex_lock (&mutex);
++data;
g_mutex_unlock (&mutex);
g_idle_add (change_label, button);
}
}
Make sure mutexes are held as little as possible. Imagine you lock a mutex in another thread and do some IO. The main loop will be stuck until the mutex is released. There is g_mutex_try_lock() that returns immidiately, but it can bring additional syncronization problems because you can't guarantee that the mutex will be unlocked when mainloop tries to lock it.
Follow up: but python is single-threaded and GIL et cetera?
You can imagine that python is multi-threaded application run on a single-core machine.
You never know when the threads will be switched. You call a GTK function but you don't know in which state the main loop is. Maybe it free'd resources just a moment before. Always schedule.
What is not discussed and further reading
Detailed documentation on glib main loop can be found here
GSource as a more low-level primitive.
GTask
I am starting a bunch of joinable worker threads and main() waits for them to completed with pthread_join(). However, a user may hit CTRL+C on the terminal before the worker threads have completed their task. My understanding is that any thread could get the signal so all my worker threads call pthread_sigmask() on start up and block SIGINT (the CTRL+C signal). This causes the signal to be copied to other threads and main(). This way I know that at least main() will get definitely the signal.
I have defined a signal handler function on main() so that main() gets the signal and can kill all the worker threads and free their resources from one place. The problem is that this happens asynchronously. I call pthread_kill() from main() and then try to free() resources the worker thread is using and it's still running because the signal is dispatched asynchronously.
If I call pthread_kill(SIGTERM, ...) from main() to kill the thread main() gets killed too and do_thread_cleanup(i) is never called:
int main () {
signal (SIGINT, signal_handler);
for (i = 0; i < num_thd; i++) {
pthread_create(thread_init, ...);
}
for (i = 0; i < num_thd; i++) {
pthread_join(...);
}
return 0;
}
void signal_handler(int signal) {
for (i = 0; i < num_thd; i++) {
pthread_kill(pthread_t, SIGINT);
pthread_join(pthread_t, ...);
do_thread_cleanup(i); // Calls functions like free() and close()
}
}
void thread_init() {
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
do_stuff_in_a_loop();
}
How can I send SIGKILL to a thread without main() receiving that signal and killing itself? Alternatively, how can I wait for the thread to exit?
Having read the other SO posts the talk about using pthread_cleanup_push() and pthread_cleanup_pop() but that doesn't allow me to check form one central place that all threads are killed and their resources released.
The short answer is that you can’t; but you can do something close.
Free(), malloc() and thus all paths leading to them are not signal safe; so you can’t call them from a signal handler. It is rare that these functions would notice the signal (re)entry, so unpredictable behaviour is the likely result.
A good pattern is to have the main thread notice signals have occurred, and perform the processing for them within it. You can do this, safely, by having the main thread employ a pthread_cond_t,pthread_mutex_t pair to watch a counter, and have the signal handler use the same pair to update the counter and notify the change.
Thus the main thread can treat signals as simple inputs to transition between states, such as Normal/SIGINT -> Quitting, Quitting/SIGALRM -> HardStop.
Free() is probably a bit heavy-handed, as it can cause your program to make sporadic memory references, which may be exploitable as an attack surface.
I'm trying to implement a sort of thread pool whereby I keep threads in a FIFO and process a bunch of images. Unfortunately, for some reason my cond_wait doesn't always wake even though it's been signaled.
// Initialize the thread pool
for(i=0;i<numThreads;i++)
{
pthread_t *tmpthread = (pthread_t *) malloc(sizeof(pthread_t));
struct Node* newNode;
newNode=(struct Node *) malloc(sizeof(struct Node));
newNode->Thread = tmpthread;
newNode->Id = i;
newNode->threadParams = 0;
pthread_cond_init(&(newNode->cond),NULL);
pthread_mutex_init(&(newNode->mutx),NULL);
pthread_create( tmpthread, NULL, someprocess, (void*) newNode);
push_back(newNode, &threadPool);
}
for() //stuff here
{
//...stuff
pthread_mutex_lock(&queueMutex);
struct Node *tmpNode = pop_front(&threadPool);
pthread_mutex_unlock(&queueMutex);
if(tmpNode != 0)
{
pthread_mutex_lock(&(tmpNode->mutx));
pthread_cond_signal(&(tmpNode->cond)); // Not starting mutex sometimes?
pthread_mutex_unlock(&(tmpNode->mutx));
}
//...stuff
}
destroy_threads=1;
//loop through and signal all the threads again so they can exit.
//pthread_join here
}
void *someprocess(void* threadarg)
{
do
{
//...stuff
pthread_mutex_lock(&(threadNode->mutx));
pthread_cond_wait(&(threadNode->cond), &(threadNode->mutx));
// Doesn't always seem to resume here after signalled.
pthread_mutex_unlock(&(threadNode->mutx));
} while(!destroy_threads);
pthread_exit(NULL);
}
Am I missing something? It works about half of the time, so I would assume that I have a race somewhere, but the only thing I can think of is that I'm screwing up the mutexes? I read something about not signalling before locking or something, but I don't really understand what's going on.
Any suggestions?
Thanks!
Firstly, your example shows you locking the queueMutex around the call to pop_front, but not round push_back. Typically you would need to lock round both, unless you can guarantee that all the pushes happen-before all the pops.
Secondly, your call to pthread_cond_wait doesn't seem to have an associated predicate. Typical usage of condition variables is:
pthread_mutex_lock(&mtx);
while(!ready)
{
pthread_cond_wait(&cond,&mtx);
}
do_stuff();
pthread_mutex_unlock(&mtx);
In this example, ready is some variable that is set by another thread whilst that thread holds a lock on mtx.
If the waiting thread is not blocked in the pthread_cond_wait when pthread_cond_signal is called then the signal will be ignored. The associated ready variable allows you to handle this scenario, and also allows you to handle so-called spurious wake-ups where the call to pthread_cond_wait returns without a corresponding call to pthread_cond_signal from another thread.
I'm not sure, but I think you don't have to (you must not) lock the mutex in the thread pool before calling pthread_cond_signal(&(tmpNode->cond)); , otherwise, the thread which is woken up won't be able to lock the mutex as part of pthread_cond_wait(&(threadNode->cond), &(threadNode->mutx)); operation.
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;
}
}
}