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

Using Coroutines in C++ for System Programming

We are almost at the end of our book. The final chapter is dedicated to a feature that is very useful for the purposes of system programming but is fairly new to the C++ standard. Coroutine objects found their application fast, becoming first-class state machine objects. Their power is in hiding logic behind the coroutine frame. Be advised that this is an advanced topic, and the coroutine interface of C++ is neither simple nor comfortable to use. It is well thought out but definitely not the most user-friendly in comparison to other programming languages.

In this chapter, you will learn the basics of using this facility. If you are new to it, then you’ll spend some time understanding its requirements. You’ll have an easier time with coroutines if you have previous experience with them in other programming languages. Still, we will use this chapter to propose their application in system programming.

We will present two...

Technical requirements

In order to run the code examples, you must prepare the following:

Introducing coroutines

At the end of your journey, we’d like to remind you about the knowledge you received in Chapter 1 and Chapter 2 about processes and threads. If you remember well, a process is simply a running instance of a program. It has its respective address space, which is not shared with others, except through shared memory. Threads reside in a process, and they cannot exist outside of them, although both processes and threads are treated as tasks in Linux. They are scheduled in the same manner and have the same controlling structures on the kernel level. Still, threads are considered lightweight because the bigger overhead for the initial load of a program is taken by the parent process.

But this is not the full picture. There are fibers and coroutines as well. If the processes and threads are truly concurrent and working in parallel over shared resources, fibers are just like threads but are not concurrency-compliant. While threads often depend on preemptive...

Network programming and coroutines in C++

In Chapter 7, you learned about the TCP and UDP communication protocols. We discussed their usefulness in network data transfer, but coroutines make them even more powerful. As mentioned, the code will behave in an asynchronous way, but we have control over the scheduling. Coroutines will be more efficient in context switching as they are executed on the user level. We’ll continue with the Generator definition to match the type of the coroutine, as discussed earlier. Traditionally, that object is made move-only – this allows us to restrict the usage of the coroutine wrapper, but in general cases, coroutine objects are non-copyable and non-moveable, because the coroutine frame is a part of them, and some local variables can be references or pointers to other local variables. Thus, let’s extend the structure accordingly:

Important note

This, again, is a very generic pattern that is used in almost every coroutine example...

Revisiting the shared memory problem through coroutines in C++

One of the issues we had with condition variables was synchronization during process startup. In other words, for the producer-consumer example, we didn’t know which threads were going to be first. We synchronized the code through a condition variable – its mutex, together with a predicate in order to handle the correct sequence of events. Otherwise, we would’ve risked losing information or ending in a deadlock. For a good portion of this book’s example preparations, we got to this situation, which made the writing experience even better. But coroutines provide another way of doing it, which could be more efficient at times and simpler to use (after you get used to the interface of coroutines as it is not the easiest to grasp).

The next example is motivated by the awaitable-awaiter pattern. It is similar to the condition variable, but it doesn’t use such synchronization primitives....

Final thoughts on coroutines and their implementations in C++

The examples earlier were practical, although not so simple. They were useful in understanding the sequence that a coroutine’s execution might take. It is good to visualize the state graph of coroutines, although we still believe it would be confusing for inexperienced developers.

As presented earlier, Figure 10.2, Figure 10.3, and Figure 10.4 pretty much cover what we’ve already explained through the code examples. It is useful to understand how much additional logic is generated around the coroutine and its members. Most of it happens in the background, and the system programmer only arranges the scheduling. In this chapter’s examples, we did this through the promise object and awaitables. The fact that the aforementioned figures partially represent a coroutine’s execution as a finite state machine should hint to you that this is another application where coroutines are useful. They transform...

Summary

With this, we’ve covered all the topics of this book. With the upcoming improvements of C++23, coroutines and their evolution will be analyzed more and more, especially in the system programming domain – and applied there, of course. Although complex to understand at first, coroutines allow you to continue sharpening the usage of C++ and give you one more instrument to enhance code.

In this chapter, you learned how to apply them in your concurrent applications, but their usefulness is far greater. We are excited about what comes next. We expect the modules language feature, which we didn’t cover in this book – intentionally – to be fully covered by the compilers and be broadly applied. Another interesting feature is std::generator – a view for the synchronous creation of coroutines in C++23. Stackful coroutines in C++26 are going to be a splendid system programming technique. In that version, you will also be able to obtain and visualize...

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