home page -> teaching -> parallel and distributed programming -> Lecture 4 - Higher level multithreading concepts

Lecture 4 - Higher level multithreading concepts

Thread creation issues

Creating many threads has two issues:

  1. creating threads, and swithcing between threads, is expensive;
  2. there is an OS-dependent upper limit on the number of threads.

This can be illustrated by running the program vector_sum_multithread.cpp. It attempts to compute a vector sum, creating one thread for each element (or for every specified number of consecutive elements). Sample runs:



To avoid the OS-imposed limit on the number of threads, we can suspend creating new threads when some pre-configured maximum is reached, and to resume when some of them terminate. The resulting program is neither efficient nor maintanable: vector_sum_limited_thread.cpp.

Thread pools

The idea behind a thread pool is the following: instead of creating a new thread when we have some work to do and finish it when the work is done, we do the following:

An example, with a fixed size thread pool, is given at vector_sum_thread_pool.cpp.

Producer-consumer communication

Futures and promises

This is an easier mechanism to work with, compared to the condition variables. Essentially, we have an object that exposes two interfaces:

Examples:

futures-demo1.cpp
using futures to get the result from asynchronous tasks
futures-demo1-with-impl.cpp
as above, but with a possible implementation for futures and the async() call

Producer-consumer queue

See the examples:

producer-consumer.cpp
threads communicating through producer-consumer queues
ProducerConsumer.java
same, but in Java
producer-consumer2.cpp
same, but the queues have limited length and enqueueing blocks if the queue is full
Radu-Lucian LUPŞA
2020-11-02