Adi Levin's Blog for programmers

August 1, 2009

Multithreading Patterns #2 – background thread

Filed under: Multithreading — Adi Levin @ 9:17 am
Tags: , ,

Typically, the main thread of an application performs all UI operations, such as responding to mouse events, updating windows and drawing graphics. If a long computation is performed in the main thread, the application is non-responsive until the computation is over. The purpose of a background thread is to enable responsiveness. The application will keep responding to user input while a computation is performed in the background.

In addition to running the long computation, a background thread should:

1. Report progress, i.e. report what percentage of the computation is done, or estimate the time left to completion.

2. Enable to abort at any moment.

3. Signal an event or send a message when the computation is completed.

Implementation of a background thread

To start the operation, create a thread using CreateThread. Inside the thread function, you need to constantly check the value of a variable that is used for abort requests. When the value of that variable is non-zero, you should abort the computation. When the computation is done, signal an event, or send a message to the main application window.

It is best to encapsulate all of that in a base class that has a pure-virtual function “run()” that should be overriden by any instance of background thread.

Communicating with the main thread

It is nice to report the progress of the computation to the user by a visual progress bar. A dialog in the main thread should have a timer that constantly update the position of the progress bar according to a variable which is constantly updated by the background thread function. The value of the progress variable should be zero at the beginning, and gradually reach 100 at the end of the computation.

For thread-safety, event handlers must be aware of the fact that the background thread is running. Each event handler should fall in one of these categories:

1. The operation can run safely while the background thread is running.

2. The operation is disabled while the background thread is running.

3. The operation is enabled, but before it begins, we must first abort the background thread.

In case of abort, we politely ask the background thread to abort, by setting the value of a certain flag, and then we wait until the background thread is completed. Do not force a thread to terminate using TerminateThread. When a thread is terminated using TerminateThread, the stack is not freed (typically 1MB), and critical sections that are owned by the thread are not released – which is a cause for deadlocks. For example, heap allocation uses a global critical section, so terminating a thread that does dynamic allocation can cause a deadlock. The worst thing about it is that these deadlocks happen at a very small probability, so it is hard to catch and debug them. In short – the thread should always end by returning from the thread function.

During the background computation, or at the end of it, sometimes we need to update data that should only be accessed by the main thread. For example, the main thread is responsible for drawing, so when we need to update data that is accessed by drawing routines, we have to use explicit synchronization mechanisms (e.g. mutex), or we must update the data on the main thread, which guarantees that the update will not occur while drawing. For details on how to do that, see the pattern “call in main thread“.

Advertisements

1 Comment »

  1. […] by Multithreading Patterns #2 – background thread « Adi Levin's Blog for programmers — August 28, 2009 @ 12:53 pm | […]

    Pingback by Multithreading Patterns #3 – Call In Main Thread « Adi Levin's Blog for programmers — August 28, 2009 @ 12:56 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:

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: