Synchronous and Asychronous Programming
-
Synchronous
- Wait for each task to complete
-
Asychronous
- Continue without waiting for tasks to complete
Synchronous Programming
- A task starts another task
- The current task is blocked
- Must wait until the new task completes before it can continue
- e.g. Synchronous database access
- Do some work
- Request data from database
- Wait for data
- Receive data from database
- Continue working
Synchronous Tasks
- Normal function calls are Synchronous Tasks
data.save(filename);
// Stop and wait for func to return
// ... wait ...
// Now we can continue with the next operation
-
We have to stop and wait for the save operation to complete
- Even if the next operation does not depend on it
-
This reduces throughput and user satisfaction
- GUI applications appear unresponsive
- Clients experience slow service
Asychronous Programming
- A task starts another task
- The current task can continue
- The new task runs in the background
- e.g. Asychronous database access
- Request data from database as a separate task
- Do some more work in our task
- Receive data from database
Asychronous Tasks
- Start off another task
data.async_save(filename);
// The Asychronous task runs in the background
// We continue with the next operation
// ... do something else ...
- Our thread can continue its work
// At some point, we may need to check if the async call has completed
// Or to get its result
Advantages of Asychronous Programming
-
The current task can do other work
- Provided it does not require the data
-
The current task only blocks when it needs the data
- If the data is already available, it can continue without stopping
-
This maintains throughput and user satisfaction
- GUI applications appear responsive
- Clients experience normal service
Blocking and Multi Threading Programs
-
Blocking is undesirable in threaded programs
- Blocking reduces throughput and responsiveness of the blocked thread
- Any threads which join with this thread will also be blocked
-
Particularly in a critical section
- Any threads which are waiting to enter the critical section are also locked
- Possibility of deadlock, if we are using locks
-
Using Asychronous programming reduces the need to block
- But may not avoid it completely
- e.g. if the database fetch is not complete when the data is needed
Blocking Synchronization
-
Blocking operations
-
Synchronized by mutexes
- A thread is blocked until another thread unlocks the mutex
-
Or atomic operations
- A thread is blocked until another thread completes an atomic operation
Non-Blocking Synchronization
-
Non-blocking operations
-
Synchronized by message queues
- A thread pushes a message onto a concurrent queue
- Another thread takes the message off the queue and processes it
- The first thread continues running without waiting
-
The messages often consist of callable objects
- The message is processed by invoking the callable object
-
C++ does not have a standard concurrent queue
- Available in Boost, Microsoft's PPL, Intel's TBB
Asynchronous Programming and Parallelism
-
Asynchronous programming
-
Can be used to perform parallel operations
- Start new threads which all perform the same task
- Collect the result from each thread as it completes its task
- Combine the results into the final answer
-
It can also be used in single threaded programs
- Using operating system features