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

Proceeding with Inter-Process Communication

The previous chapter presented many features of C++20 that allow you to execute tasks in parallel. Outside of the global variables, it didn’t cover ways to communicate between processes or threads. On a system level, most of the asynchronous calls are born in the continuous communication between processes and different computer systems.

In this chapter, you will learn about the inter-process communication (IPC) interfaces that Linux provides. Through them, you will get a full picture of possibilities to cover your system and software requirements. You’ll start by learning about message queues (MQs) as a continuation of the discussion about pipes in Chapter 3. In addition, we will analyze in detail the work of the semaphore and mutex synchronization techniques. We will introduce you to some new C++20 features in this area that are easy to use, and you will no longer have to implement such yourself.

This allows us to proceed...

Technical requirements

To run the code examples, you must prepare the following:

Introducing MQs and the pub/sub mechanism

We’re glad to be back on the IPC topic. The last time we discussed it was in Chapter 3, where we explained pipes and used some code examples. You learned about the basic mechanism of exchanging data between processes, but as you remember, there are some blocking points. As with any programming instrument, pipes have particular usage – they are fast, and they can help you send and receive data from both related (forked) processes (through anonymous pipes) and unrelated processes (through named pipes).

In a similar fashion, we could use MQs to transfer data, which are available to related and unrelated processes, too. They provide the ability to send a single message to multiple receiving processes. But as you saw, pipes are primitive in the sense of sending and receiving binary data as is, while MQs bring the notion of a message to the table. The policy of the transfer is still configured in the calling process – queue...

Guaranteeing atomic operations through semaphores and mutual exclusions

Let’s try to zoom in on a shared resource and see what happens in the CPU. We will provide a simple and effective way to explain where exactly the data races start from. They were already thoroughly discussed in Chapter 6. Everything we learn here should be considered as an addition, in a sense, but the analysis methodology of concurrent and parallel processing remains the same as earlier. But now, we focus on concrete low-level problems.

Let’s look closely at the following snippet:

int shrd_res = 0; //Some shared resource.
void thread_func(){
    shrd_res ++;
    std::cout << shrd_res;
}

It is a very simple piece of code in which a variable is incremented and printed out. According to C++ standards, such a modification is an undefined behavior in multithreaded environments. Let’s see how – instead of going through the process’...

Using shared memory

As with pipes, the MQ data is lost once consumed. Duplex message data copying increases user space-kernel space calls, therefore an overhead is to be expected. The shmem mechanism is fast. As you learned in the previous chapter and the previous section, the synchronization of the data access is an issue that must be resolved by the system programmer, especially when it comes to race conditions.

An important remark is that the term shared memory is vague in itself. Is it a global variable that two threads could access simultaneously? Or is it a shared region of RAM, which multiple CPU cores use as a common ground to transfer data between each other? Is it a file in the filesystem that many processes modify? Great questions – thanks for asking! In general, all of those are kinds of shared resources, but when we speak about the term memory, we should really think about a region in the main memory that is visible to many processes and where multiple tasks...

Communicating through the network with sockets

If the pipes, MQs, and the shmem could together overcome their problems, then why do we need sockets? This is a great question with a simple answer – we need them to communicate between different systems on the network. With this, we have our full set of instruments to exchange data. Before we understand sockets, we need to get a quick overview of network communication. No matter the network type or its medium, we must follow the design established by the Open Systems Interconnection (OSI) basic reference model. Nowadays, almost all OSs support the Internet Protocol (IP) family. The easiest way to set up communications with other computer systems is by using these protocols. They follow layering, as described in the ISO-OSI model, and now we are going to take a quick look at that.

Overview of the OSI model

The OSI model is typically represented as shown in the next table. System programmers usually require it to analyze where...

Summary

In this chapter, you’ve learned about various ways to execute IPC. You got familiar with MQs as simple, real-time, and reliable instruments for sending small chunks of data. We also got into the details of fundamental synchronization mechanisms such as semaphores and mutexes, along with their C++20 interfaces. In combination with shmem, you observed how we could exchange large amounts of data fast. At the end, the network communication through sockets was introduced to you through the main protocols, UDP and TCP.

Complex applications usually rely on multiple IPC techniques to achieve their goals. It’s important to be aware of them – both their strengths and their disadvantages. This will help you decide on your particular implementation. Most of the time, we build layers on top of IPC solutions in order to guarantee the robustness of an application – for example, through retry mechanisms, polling, event-driven designs, and so on. We will revisit...

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