1

I am experience deadlock while trying to use WIN32 API from additional thread. The additional thread is needed in my application to improve Frame Rate. It actually helps, however, I get deadlocks in almost all of the system functions:

::ShowWindow ::MoveWindow ::UpdateWindow

I know that ShowWindow() for example, may be replaced with ShowWindowAsync() and it does solves the problem, however, there are no such alternatives in MoveWindow() and UpdateWindow().

Did someone experienced those problems, what is solution?

Thanks!

Iron-Eagle
  • 1,707
  • 2
  • 17
  • 34
  • Have you used some synchronization on those threads? Semaphore,mutex? (Are they accessing each others data?) – Dejan Jun 02 '13 at 10:29
  • The main thread are sometimes called the `UI Thread` for a reason. UI operations are better queued in the main thread. Though I don't know if this is as deadly in Windows. – BlueWanderer Jun 02 '13 at 10:41
  • Is the first thread pumping messages? See also this old question http://stackoverflow.com/questions/770503/movewindow-deadlock – Daniel Flassig Jun 02 '13 at 10:43
  • 1
    It is an open question whether User32 is thread-safe or not. A Microsoft guy like Raymond Chen will tell you "yes, but it is the window procedure that's never thread-safe". Which is a long-winded way of passing the buck and saying "no". This just *never* comes to a good end. Focus on using threading in the code that generates the window **content**. The part that's truly where the slowdown is located. And much easier to get right since that's all your code. – Hans Passant Jun 02 '13 at 16:32

2 Answers2

1

The term "deadlock" describes a very specific thing, two threads waiting for access to a resource that is locked by the other. There is no indication that this is what is happening in your case (or is there?), so what exactly is it that you are experiencing? Also, what exactly is it that you want to achieve with multithreading?

In any case, keep the UI in a single thread, use SendMessage() & Co to notify that thread of any events occurring in background threads. Alternatively, you can also use a timer to poll for certain state changes. That way, you are on the safe side and your application shouldn't lock up (at least not because of using the UI from different threads).

To be a bit more precise, you have to keep the message loop for a window and all its child windows in a single thread. You can create multiple windows and handle each of them from their own thread, but don't mix calls. In practice, this distinction isn't important though, because few applications create multiple windows (and no, e.g. a message box or other dialogs don't count).

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
1

All the API functions that you refer to have in common that they send(!) some message to the target window. UpdateWindow is probably the most obvious, because it needs to send WM_PAINT. Notice also that it "sends" the message and doesn't post to the queue (for UpdateWindow, the MSDN documentation calls this out explicitly, for the others it may be less obvious).

Also notice that windows have thread affinity as alluded to in some of the comments. Among other things this means that messages to that window are only ever received/dispatched on one thread. If you send a message to a window of another thread, the operating system is left with the task to determine when it should dispatch that message (i.e. call the window procedure). This (dispatching incoming sent messages) only happens during certain API calls during which it can be assumed to be safe to invoke the window procedure with a random message. The relevant times are during GetMessage and PeekMessage*.

So if your window owning thread (also called UI thread) is pumping messages normally, incoming sent messages are also quickly dispatched. From your question it seems however, that your UI thread is currently busy. If the second thread then invokes one of said functions, then it will block until the first thread provides a chance to have the sent messages dispatched.

As others have said, it is usually a good idea to keep user interface code on one dedicated UI thread (although exceptions - as always - prove the rule). And it is definitely necessary (for a good user experience) to have window owning threads be responsive to messages at all times. If your UI thread also has to wait on some synchronization objects, you may find MsgWaitForMultipleObjects helpful.

*the list might not be complete.

Daniel Flassig
  • 678
  • 4
  • 8
  • Thank you very much for the answer. Unfortunately it is not that simple to keep everything in one thread in my case since I am writing plugin for another application, and this other application choose to call the window from the another thread. – Iron-Eagle Jun 04 '13 at 14:59
  • Whatever the details of your architecture may be, the take-away message is: the window owning thread needs to be pumping messages. Otherwise APIs like UpdateWindow cannot be called. What you could of course do is define some WM_APP specific messages to tell the window to resize itself and post those to the queue (I'm not saying such a design is advisable) – Daniel Flassig Jun 04 '13 at 16:33