liveBook · Manning

Concurrency

As explained in C++ Concurrency in Action, Second Edition

Concurrency is the structuring and execution of multiple tasks whose progress overlaps, whether or not they run at the exact same time.

Concurrency lets multiple activities make progress without requiring each to finish before the next begins. On one core, task switching can create that effect by alternating between activities; multiple cores can execute them in parallel. The distinction matters: behavior observed under task switching may not expose incorrect assumptions about memory. section 1.1.1

Figure 1.1. Two approaches to concurrency: parallel execution on a dual-core machine versus task switching on a single-core machine

Compare alternating execution on one core with parallel execution on two cores. Both support concurrent activities, but only the latter runs them at the same instant. section 1.1.1

An application can organize concurrent work in two basic ways:

  • Use separate processes that communicate through mechanisms such as sockets, files, or pipes. Process isolation protects data, but communication and process creation have costs. section 1.1.2
  • Use multiple threads in one process. Shared resources make communication easier, but they also require care when threads use those resources. section 1.1.2

Choose concurrency to separate responsibilities or to improve performance. A user-interface thread can handle input while another thread does lengthy work. For throughput, task parallelism divides work into parts; data parallelism applies the same operation to different parts of the data. The term parallelism emphasizes performance, while concurrency often emphasizes separation of concerns or responsiveness; the uses overlap. section 1.1.3 section 1.2.1 section 1.2.2

Keep an event loop responsive

A GUI loop repeatedly gets an event and processes it. If that same thread performs a lengthy task, it must interrupt the task to check for input. Instead, start a task thread on a start event and leave the GUI thread to process events. A stop event sets a cancellation flag and joins the task thread; successful completion posts an event so the GUI handler can join the thread and display results. section 8.4.4

Listing 8.6. Separating GUI thread from task thread
std::thread task_thread;
std::atomic<bool> task_cancelled(false);
void gui_thread()
{
    while(true)
    {
        event_data event=get_event();
        if(event.type==quit)
            break;
        process(event);
    }
}
void task()
{
    while(!task_complete() && !task_cancelled)
    {
        do_next_operation();
    }
    if(task_cancelled)
    {
        perform_cleanup();
    }
    else
    {
        post_gui_event(task_complete);
    }
}
void process(event_data const& event)
{
    switch(event.type)
    {
    case start_task:
        task_cancelled=false;
        task_thread=std::thread(task);
        break;
    case stop_task:
        task_cancelled=true;
        task_thread.join();
        break;
    case task_complete:
        task_thread.join();
        display_results();
        break;
    default:
        //...
    }
}

Follow the start, stop, and completion cases alongside the worker’s cancellation check to see where the two threads interact. section 8.4.4

Do not add threads automatically. Thread creation consumes time and resources, and too many threads can slow a system or exhaust available resources. Concurrency also makes code harder to understand and maintain. Use it when responsiveness, clearer separation, or expected performance gains justify those costs; designing the interactions correctly is the difficult part. section 1.2.3 section 1.5

How C++ Concurrency in Action, Second Edition covers it

How deep it goes
Defines concurrency, compares execution and organization models, and walks through a GUI-worker outline without detailing memory-model rules.
Examples
Uses single-core and dual-core execution, a DVD player’s playback and input, and a GUI event loop with a worker thread.
What it assumes
Assumes a C++ application context but introduces concurrency and its motivations without requiring prior concurrency experience.
What you can do after
Apply it via C++ Standard Library threads to separate lengthy work from GUI event handling, while weighing threading costs.
How it connects
Connects concurrency to task switching, parallelism, processes, threads, separation of concerns, task parallelism, and data parallelism.

Also explained in

Compare how 23 books explain concurrency →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C++ Concurrency in Action, Second Edition. The section links point to the parts of the book it draws on.