Concurrency


Benefits of Concurrency

There are a number of situations where threads can greatly simplify writing elegant and efficient programs. The sorts of problems where threads can be very useful include.

Blocking IO.
Programs that do a lot of IO have three options. They can either do the IO serially, waiting for each to complete before commencing the next. They can use Asynchronous IO, dealing with all the complexity of asynchronous signals, polling or selects. They can use synchronous IO, and just spawn a sperarate thread/process for each IO call. In this case threading can significantly improve both performance and code complexity.
Multiple Processors.
If you are using a threads library that supports multiple processors, you can gain significant performance improvements by running threads on each processor. This is particularly useful when your program is compute bound.
User Interface.
By separating the user interface, and the program engine into different threads you can allow the UI to continue to respond to user input even while long operations are in progress.
Servers.
Servers that serve multiple clients can be made more responsive by the appropriate use of concurrency. This has traditionally been achieved by using the fork() system call. However in some cases, especially when dealing with large caches, threads can help improve the memory utilisation, or even permit concurrent operation where fork() was unsuitable.

However there are problems when multiple threads share a common address space. The biggest problem concerns data races.
Consider the following code:

THREAD 1                THREAD 2
a = data;               b = data;
a++;                    b--;
data = a;               data = b;

Now if this code is executed serially (THREAD 1, the THREAD 2) there isn't a problem. However threads execute in an arbitrary order, so consider this:

THREAD 1                THREAD 2
a = data;
                        b = data;
a++;
                        b--;
data = a;
                        data = b;
[data = data - 1!!!!!!!]

So data could end up +1, 0, -1, and there is NO way to know which as it is completely non-deterministic!

In fact the problem is worse, because on many machines a = data is non-atomic. This means that when data is loaded into a, you could end up with the low order bits of the old data, and the high order bits of the new data. CHAOS.

The solution to this is to provide functions that will block a thread if another thread is accessing data that it is using.

Pthreads use a data type called a mutex to achieve this.

<<< Contents >>>


Andrae Muys