Reader small image

You're reading from  C++ Programming for Linux Systems

Product typeBook
Published inSep 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781805129004
Edition1st Edition
Languages
Right arrow
Authors (2):
Desislav Andreev
Desislav Andreev
author image
Desislav Andreev

Desislav Andreev is a software engineer with a PhD in artificial intelligence systems and quantum machine learning. He has several publications in software engineering and AI applications. For his 10 years in the field he has a demonstrated history of working in automotive software engineering and in the area of the higher education. He is skilled in system and software architectures, operating systems, C and C++ development, autonomous driving and computer graphics. He is currently working as a Lead C++ Developer in VMware, developing its core software functionalities. He is also a lecturer at the Technical University of Sofia. He was previously a Technical Professional and software architect in the CRE and ADAS departments of Visteon Corporation, working closely with both OEMs and development teams.
Read more about Desislav Andreev

Stanimir Lukanov
Stanimir Lukanov
author image
Stanimir Lukanov

Stanimir Lukanov is a C++ expert, software tech lead and architect at VMWare. He has more than 15 years of professional experience in writing efficient and robust C++ enterprise code. Stanimir is a member of the Bulgarian National Body which is part of The C++ Standards Committee (JTC1/SC22/WG21). His interests are in the area of software security for distributed enterprise software systems. Since 2017 he has worked at VMWare where he currently leads a team which develops core security functionality in one of the major products in the company's portfolio. Before joining VMWare he held the position of senior software engineer at Visteon Corporation and Johnson Controls. He was responsible for defining software architecture, making code reviews, leading C++ training and delivering fast and robust C++ code for real-time automotive embedded systems.
Read more about Stanimir Lukanov

View More author details
Right arrow

Concurrent System Programming with C++

In this chapter, we will look at what concurrency means and how it is different from parallelism. We will go through the fundamentals and the theory behind processes and threads. We will look at the changes in the C++ memory model, which enforce native concurrency support in the language. We will also familiarize ourselves with what a race condition is, how it can lead to a data race, and how to prevent data races. Next, we will get acquainted with the C++20 std::jthread primitive, which enables multithreading support. We will learn about the specifics of the std::jthread class and how we can stop already running std::jthread instances by using the std::stop_source primitive. Finally, we will learn how to synchronize the execution of concurrent code and how to report calculation results from executed tasks. We will learn how to use C++ synchronization primitives such as barriers and latches to synchronize the execution of concurrent tasks, and...

Technical requirements

All examples in this chapter have been tested in an environment with the following configuration:

What is concurrency?

Modern cars have become highly intricate machines that provide not only transportation but also various other functionalities. These functionalities include infotainment systems, which allow users to play music and videos, and heating and air conditioning systems, which regulate the temperature for passengers. Consider a scenario in which these features did not work simultaneously. In such a case, the driver would have to choose between driving the car, listening to music, or staying in a comfortable climate. This is not what we expect from a car, right? We expect all of these features to be available at the same time, enhancing our driving experience and providing a comfortable trip. To achieve this, these features must operate in parallel.

But do they really run in parallel, or do they just run concurrently? Is there any difference?

In computer systems, concurrency and parallelism are similar in certain ways, but they are not the same. Imagine you have...

Threads versus processes

In Linux, a process is an instance of a program in execution. A process can have one or more threads of execution. A thread is a sequence of instructions that can proceed independently of other threads within the same process.

Each process has its own memory space, system resources, and execution context. Processes are isolated from each other and do not share memory by default. They can only communicate through files and inter-process communication (IPC) mechanisms, such as pipes, queues, sockets, shared memory, and so on.

A thread, on the other hand, is a lightweight unit of execution within a process. The overhead of loading the instructions from non-volatile memory to RAM or even the cache is already paid for by the process creating the thread – the parent process. Each thread has its own stack and register values but shares the memory space and system resources of the parent process. Because threads share memory within the process, they can...

Concurrency with C++

The C++ language has had built-in support for managing and executing concurrent threads since C++11. But it doesn’t have any native support for managing concurrent processes. The C++ Standard Library provides various classes for thread management, synchronization and communication between threads, protection of shared data, atomic operations, and parallel algorithms. The C++ memory model is also designed with thread awareness in mind. This makes it a great choice for developing concurrent applications.

Multithreading with C++ is the ability to have multiple threads of execution running concurrently within a single program. This allows a program to take advantage of multiple CPU cores and perform tasks in parallel, leading to faster completion of tasks and improved overall performance.

The C++ Standard Library introduced the std::thread thread management class. Once it is instantiated, it is the responsibility of the user to take care of the thread...

Demystifying race conditions and data races

In C++, multithreading support was first introduced with the C++11 version of the language. One of the key elements provided by the C++11 standard to facilitate multithreading is the memory model. The memory model tackles two problems: the layout of objects in memory and the concurrent access to these objects. In C++, all data is represented by objects, which are blocks of memory that have various properties such as type, size, alignment, lifetime, value, and an optional name. Each object remains in memory for a specific period of time and is stored in one or more memory locations, depending on whether it is a simple scalar object or a more complex type.

In the context of multithreaded programming in C++, it is crucial to consider how to tackle concurrent access by multiple threads to shared objects. If two or more threads try to access different memory locations, there is usually no problem. However, when threads attempt to write in the...

Practical multithreading

In computer science, a thread of execution is a sequence of code instructions that can be managed independently by a scheduler of the operating system. On a Linux system, the thread is always part of a process. The C++ threads could be executed concurrently with each other via the multithreading capabilities provided by the standard. During execution, threads share common memory space, unlike processes, where each has its own. Specifically, the threads of a process share its executable code, the dynamically and globally allocated objects, which are not defined as thread_local.

Hello C++ jthread

Every C++ program contains at least one thread, and this is the thread that runs the int main() method. Multithreaded programs have additional threads started at some point in the execution of the main thread. Let’s have a look at a simple C++ program that uses multiple threads to print to the standard output:

#include <iostream>
#include <thread...

Sharing data during parallel execution

Think in terms of tasks rather than threads (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp4-think-in-terms-of-tasks-rather-than-threads).

Referring back to the C++ Core Guidelines, they advise us that it is better to stick to tasks rather than threads. A thread is a technical implementation idea, a perspective on how the machine works. On the other hand, a task is a practical concept for work that you want to do, ideally alongside other tasks. In general, practical concepts are simpler to understand and provide better abstraction, and we prefer them.

But what is a task in C++? Is it another standard library primitive or what? Let’s have a look!

In C++, besides threads, tasks are also available to perform work asynchronously. A task consists of a worker and two associated components: a promise and a future. These components are connected through a shared state, which is a kind of data channel. The promise does...

Summary

In this chapter, we explored several topics related to concurrency and parallelism in C++. We began by discussing the terminology and differences between concurrency and parallelism, including preemption. We then delved into how programs execute on single and multiple processing units, distinguishing between processes and execution threads and briefly exploring communication mechanisms such as pipes, sockets, and shared memory.

In the context of C++, we examined how the language supports concurrency, specifically through the std::thread class and the new std::jthread primitive introduced in C++20. We also discussed the risks associated with race conditions and data races, including an example of a money transfer operation. To avoid these issues, we examined mechanisms such as locks, atomic operations, and memory barriers.

Moving on, we looked closely at the std::jthread class, exploring its functionality and proper usage. Additionally, we learned about a new synchronized...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
C++ Programming for Linux Systems
Published in: Sep 2023Publisher: PacktISBN-13: 9781805129004
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Authors (2)

author image
Desislav Andreev

Desislav Andreev is a software engineer with a PhD in artificial intelligence systems and quantum machine learning. He has several publications in software engineering and AI applications. For his 10 years in the field he has a demonstrated history of working in automotive software engineering and in the area of the higher education. He is skilled in system and software architectures, operating systems, C and C++ development, autonomous driving and computer graphics. He is currently working as a Lead C++ Developer in VMware, developing its core software functionalities. He is also a lecturer at the Technical University of Sofia. He was previously a Technical Professional and software architect in the CRE and ADAS departments of Visteon Corporation, working closely with both OEMs and development teams.
Read more about Desislav Andreev

author image
Stanimir Lukanov

Stanimir Lukanov is a C++ expert, software tech lead and architect at VMWare. He has more than 15 years of professional experience in writing efficient and robust C++ enterprise code. Stanimir is a member of the Bulgarian National Body which is part of The C++ Standards Committee (JTC1/SC22/WG21). His interests are in the area of software security for distributed enterprise software systems. Since 2017 he has worked at VMWare where he currently leads a team which develops core security functionality in one of the major products in the company's portfolio. Before joining VMWare he held the position of senior software engineer at Visteon Corporation and Johnson Controls. He was responsible for defining software architecture, making code reviews, leading C++ training and delivering fast and robust C++ code for real-time automotive embedded systems.
Read more about Stanimir Lukanov