Adi Levin's Blog for programmers

August 1, 2009

Multithreading Patterns #3 – Call In Main Thread


This pattern is very useful when using the “background thread” pattern. Typically, the main thread is responsible for all UI operations (handling events and drawing controls and graphics).  When a background computation is performed in a different thread, you sometimes need to update controls (such as text controls) or data that is used for drawing (such as geometric data, surfaces and images), when certain stages of the computation are completed. For example, an application that renders a movie scene may want to update the movie and at the same time enable to watch the part of the scene that was created so far.

An elegant way to achieve this is to perform all updates of the document data in the main thread only. The heavy computation is done in the background, and only when a certain stage is reached, we call a function in the main thread that makes the update of the document data.


Typically, the main thread has a message loop that spends most of its time waiting for user input, and is associated with the main window of the application. So, in order to run a certain function in the main thread, we need to send a message to the application main window. The parameters of the message LPARAM and WPARAM define what function should invoked, and what parameter it should take as input.

The window procedure that handles messages should recognize these special messages by their message identifier (which can be WM_APP + x), and call the needed function. This should be encapsulated nicely into a class, so that anyone who wants to place a call in the main thread will only need to give the function pointer and the parameter (a pointer as well).

Two types of calls – SendMessage & PostMessage

Since we perform the call-in-main-thread via messages, we need to choose between sending and posting a message. Sending a message from the background thread means that you halt the background computation until the function is called in the main thread and is completed. Posting a message means that you don’t halt the computation. Depending on the circumstances of your application, you should decide which of them to use (see my post on messages and message loop for the issues related to SendMessage and PostMessage).

Calls made by SendMessage are simple to implement, but they can cause a deadlock if you’re not careful (because the background thread waits for the main thread, while the main thread may be waiting for the background thread). Because of that, it is often safer to use PostMessage. However, when you use PostMessage you need to make sure that the parameter you send for the function call remains valid at the time that the call will actually be performed, which can be far in the future (when the main thread is ready), long after the background computation has completed.

One way to deal with this problem is to make a special call at certain places in the code that causes all pending function calls to be either ignored or performed – depending on what your application needs. One way to support this functionality is to keep a table of all posted calls (function pointer and parameter), so that at any moment we have access to the list of function calls that are waiting to be executed.


1 Comment »

  1. […] that the update will not occur while drawing. For details on how to do that, see the pattern “call in main thread“. Leave a […]

    Pingback by Multithreading Patterns #2 – background thread « Adi Levin's Blog for programmers — August 28, 2009 @ 12:53 pm | Reply

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Create a free website or blog at

%d bloggers like this: