Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multi Threading

56 views
Skip to first unread message

Derek Baker

unread,
Oct 31, 2003, 8:26:32 AM10/31/03
to
I understand that you should put all the GUI in the main thread. The
question I have is what would be the effect of not doing it that way?

--
Derek


Scott McPhillips [MVP]

unread,
Oct 31, 2003, 7:52:21 PM10/31/03
to
Derek Baker wrote:

> I understand that you should put all the GUI in the main thread. The
> question I have is what would be the effect of not doing it that way?
>

Interthread communication and synchronization is difficult and
error-prone. Introducing those difficulties between GUI objects
needlessly complicates the design and adds opportunities for error.
Keep thread functions and inter-thread communications as simple as
possible to minimize bugs.

--
Scott McPhillips [VC++ MVP]

Robert Scott

unread,
Nov 2, 2003, 10:50:07 PM11/2/03
to

As a follow-on question, what would be the repercussions of doing
this: a worker thread calls SetWindowText for a window whose window
proc belongs to the main UI thread. I try to avoid doing this on
general principles, but on occasions when I have done it accidentally,
it worked just fine. Is this type of thing safe, or was I just lucky?


-Robert Scott
Ypsilanti, Michigan
(Reply through newsgroups, not by direct e-mail, as automatic reply address is fake.)

Scott McPhillips [MVP]

unread,
Nov 3, 2003, 12:16:20 AM11/3/03
to
Robert Scott wrote:
>>Interthread communication and synchronization is difficult and
>>error-prone. Introducing those difficulties between GUI objects
>>needlessly complicates the design and adds opportunities for error.
>>Keep thread functions and inter-thread communications as simple as
>>possible to minimize bugs.
>
>
> As a follow-on question, what would be the repercussions of doing
> this: a worker thread calls SetWindowText for a window whose window
> proc belongs to the main UI thread. I try to avoid doing this on
> general principles, but on occasions when I have done it accidentally,
> it worked just fine. Is this type of thing safe, or was I just lucky?

Accessing a window that belongs to the main thread sends a message that
must be handled by the main thread. In itself this is safe and
guaranteed to work. But if the main thread is busy or blocked then the
sending thread is suspended and has to wait. This kind of defeats the
purpose of having a second thread, and it can cause a deadlock if the
owner thread is suspended waiting for the worker thread to exit.

Lucian Wischik

unread,
Nov 3, 2003, 6:08:30 AM11/3/03
to
Robert Scott wrote:
>As a follow-on question, what would be the repercussions of doing
>this: a worker thread calls SetWindowText for a window whose window
>proc belongs to the main UI thread. I try to avoid doing this on
>general principles, but on occasions when I have done it accidentally,
>it worked just fine. Is this type of thing safe, or was I just lucky?

Obviously it's not thread safe! That's because SetWindowText will
block on the hwnd's thread, but at the same time the main thread might
conceivably be blocking on your worker thread. -- result: deadlock.

Here (below) is a small example that exhibits the problem. The worker
thread calls "SetWindowText" every 500ms. But as soon as you click the
left button, I programmed the main thread to block on the worker
thread, and hence the entire application freezes. The technique I used
to block on the worker thread is unlikely in practice -- in practice,
instead, you'll use far more insidious and hard-to-debug modes of
blocking.

--
Lucian

#include <windows.h>
HINSTANCE hInstance;
HANDLE hAbort;
// hAbort is an asynchronous signal to tell the worker thread to
// eventually abort.
CRITICAL_SECTION critsec;
// critsec is something that the worker thread enters, and stays
// in for its entire existence. Therefore any other thread who
// tries to acquire the critsec will end up blocking on the
// worker thread.


DWORD WINAPI ThreadProc(void *param)
{ HWND hwnd = (HWND)param;
EnterCriticalSection(&critsec);
for (int i=0; WaitForSingleObject(hAbort,500)!=WAIT_OBJECT_0; i++)
{ char c[20]; wsprintf(c,"%i",i);
SetWindowText(hwnd,c);
}
LeaveCriticalSection(&critsec);
return 0;
}


LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM
lParam)
{ switch (msg)
{ case WM_LBUTTONDOWN:
{ EnterCriticalSection(&critsec);
MessageBox(hwnd,"The main window is in the
critsec","critsec",MB_OK);
LeaveCriticalSection(&critsec);
} break;
case WM_DESTROY:
{ PostQuitMessage(0);
} break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}


int WINAPI WinMain(HINSTANCE h,HINSTANCE,LPSTR,int)
{ hInstance=h;

WNDCLASS wc; ZeroMemory(&wc,sizeof(wc));
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc.lpszClassName= "LucianHasClass";
RegisterClass(&wc);
HWND hwnd = CreateWindow("LucianHasClass","A
Window",WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,0,hInstance,0);

InitializeCriticalSection(&critsec);
hAbort=CreateEvent(0,FALSE,FALSE,0);
DWORD tid; HANDLE hThread =
CreateThread(0,0,ThreadProc,hwnd,0,&tid);

MSG msg; while (GetMessage(&msg,0,0,0))
{ TranslateMessage(&msg);
DispatchMessage(&msg);
}

SetEvent(hAbort);
WaitForSingleObject(hThread,INFINITE);
DeleteCriticalSection(&critsec);
CloseHandle(hThread);
CloseHandle(hAbort);

return 0;
}

Robert Scott

unread,
Nov 3, 2003, 8:46:32 AM11/3/03
to
On Mon, 03 Nov 2003 00:16:20 -0500, "Scott McPhillips [MVP]"
<scot...@mvps.org.nowhere> wrote:

>Accessing a window that belongs to the main thread sends a message that
>must be handled by the main thread. In itself this is safe and
>guaranteed to work. But if the main thread is busy or blocked then the
>sending thread is suspended and has to wait. This kind of defeats the
>purpose of having a second thread, and it can cause a deadlock if the
>owner thread is suspended waiting for the worker thread to exit.

Ah, so if I have to do this sort of thing, I might be better to call
PostMessage with the WM_SETTEXT message, taking care that the string
referenced will persist in static memory long enough for the main
thread to handle the message...

Stephen Kellett

unread,
Nov 3, 2003, 5:46:54 AM11/3/03
to
In message <3fa5cf53...@news.wwnet.net>, Robert Scott
<no-...@nowhere-q7x.com> writes

>As a follow-on question, what would be the repercussions of doing
>this: a worker thread calls SetWindowText for a window whose window
>proc belongs to the main UI thread. I try to avoid doing this on
>general principles, but on occasions when I have done it accidentally,
>it worked just fine. Is this type of thing safe,

No, depending on your application you run the risk of Deadlock. Never
use SendMessage to send from one thread to another, use PostMessage
instead. SetWindowText uses SendMessage.

Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.demon.co.uk
RSI Information: http://www.objmedia.demon.co.uk/rsi.html

Ralf Buschmann

unread,
Nov 3, 2003, 8:49:16 AM11/3/03
to
On Mon, 03 Nov 2003 12:08:30 +0100, Lucian Wischik <lu...@wischik.com>
wrote:

>Obviously it's not thread safe!

Only if you design it to be so, IMHO :-) Just remember that the purpose
of a message loop is to process messages and nothing else and you'll be
fine.

Ralf.

Derek Baker

unread,
Nov 3, 2003, 9:42:00 AM11/3/03
to
Nice to see I started a debate, especially as I haven't decided whether or
not to implement multi-threading in my app:)

--
Derek


Jussi Jumppanen

unread,
Nov 2, 2003, 7:29:03 PM11/2/03
to
Derek Baker wrote:
>
> I understand that you should put all the GUI in the main thread. The
> question I have is what would be the effect of not doing it that way?

Every Windows application has built in thread locking in their message
queue, provided free of charge by Win32.

Now consider the case where you main process traps a windows message,
at starts a thread which then sends a message to the queue that started
the thread. In this situation, by windows design your application will
hang. This is the exact reason why functions like PostThreadMessage
exist in the Win32.

Jussi Jumppanen
Author of: Zeus for Windows (All new version 3.90 out now)
"The C/C++, Cobol, Java, HTML, Python, PHP, Perl programmer's editor"
Home Page: http://www.zeusedit.com

Ralf Buschmann

unread,
Nov 4, 2003, 4:23:10 AM11/4/03
to
On Mon, 03 Nov 2003 11:29:03 +1100, Jussi Jumppanen
<jus...@zeusedit.com> wrote:

>Now consider the case where you main process traps a windows message,
>at starts a thread which then sends a message to the queue that started
>the thread. In this situation, by windows design your application will
>hang.

Well, only if the main thread blocks on the newly created thread. I
wouldn't call this a Windows design issue but rather bad programming
practice. Just do not block on anything in a message loop. For instance,
instead of blocking on a thread handle, have the thread post a private
message when it's finished.

Ralf.

Markus Elfring

unread,
Nov 4, 2003, 5:44:20 AM11/4/03
to
> I understand that you should put all the GUI in the main thread. The
> question I have is what would be the effect of not doing it that way?

The document "How to Use Threads with Java™ (JFC/Swing)" has got
useful informations.
http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html

0 new messages