Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
C++ System Programming Cookbook
C++ System Programming Cookbook

C++ System Programming Cookbook: Practical recipes for Linux system-level programming using the latest C++ features

eBook
€20.99 €23.99
Paperback
€29.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

C++ System Programming Cookbook

Revisiting C++

This chapter acts as a refresher on C++ 11-20, which will be used throughout this book. We'll explain why C++ represents a great opportunity that shouldn't be missed when it comes to writing good quality code that's concise and more portable than ever.

This chapter does not contain all the new features introduced by C++ (11 through 20) – just the ones we will be using for the rest of this book. Specifically, you'll get a refresher (if you already know) or learn (if you are new) about the most essential new C++ skills needed to write modern code. You'll work, hands-on, with lambda expressions, atomics, and move semantics, just to mention a few.

This chapter will cover the following recipes:

  • Understanding C++ primitive types
  • Lambda expressions
  • Automatic type deduction and decltype
  • Learning how atomic works
  • Learning how nullptr works
  • Smart pointers unique_ptr and shared_ptr
  • Learning how semantics works
  • Understanding concurrency
  • Understanding the filesystem
  • The C++ Core Guidelines
  • Adding GSL to your makefile
  • Understanding concepts
  • Using span
  • Learning how Ranges work
  • Learning how modules work

Technical requirements

To let you try out the programs in this chapter immediately, we've set up a Docker image that has all the tools and libraries we'll need throughout this book. It's based on Ubuntu 19.04.

In order to set it up, follow these steps:

  1. Download and install the Docker Engine from www.docker.com.
  2. Pull the image from Docker Hub: docker pull kasperondocker/system_programming_cookbook:latest.
  3. The image should now be available. Type in the following command to view the image: docker images.
  4. Now, you should have the following image: kasperondocker/system_programming_cookbook.
  5. Run the Docker image with an interactive shell with the help of the following command: docker run -it --cap-add sys_ptrace kasperondocker/system_programming_cookbook:latest /bin/bash.
  6. The shell on the running container is now available. Use root@39a5a8934370/# cd /BOOK/ to get all the programs that have been developed for the chapters in this book.

The --cap-add sys_ptrace argument is needed to allow GDB to set breakpoints in the Docker container which, by default, Docker does not allow.

Disclaimer: The C++20 standard has been approved (that is, technically finalized) by WG21 in a meeting in Prague at the end of February. This means that the GCC compiler version that this book uses, 8.3.0, does not include (or has very, very limited support for) the new and cool C++20 features. For this reason, the Docker image does not include the C++20 recipe code. GCC keeps the development of the newest features in branches (you have to use appropriate flags for that, for example, -std=c++2a); therefore, you are encouraged to experiment with them by yourself. So, clone and explore the GCC contracts and module branches and have fun.

Understanding C++ primitive types

This recipe will show all the primitive data types defined by the C++ standard, as well as their size.

How to do it...

In this section, we'll have a closer look at what primitives the C++ standard defines and what other information is important. We'll also learn that although the standard does not define a size for each, it defines another important parameter:

  1. First, open a new Terminal and type in the following program:
#include <iostream>
#include <limits>

int main ()
{
// integral types section
std::cout << "char " << int(std::numeric_limits<char>::min())
<< "-" << int(std::numeric_limits<char>::max())
<< " size (Byte) =" << sizeof (char) << std::endl;
std::cout << "wchar_t " << std::numeric_limits<wchar_t>::min()
<< "-" << std::numeric_limits<wchar_t>::max()
<< " size (Byte) ="
<< sizeof (wchar_t) << std::endl;
std::cout << "int " << std::numeric_limits<int>::min() << "-"
<< std::numeric_limits<int>::max() << " size
(Byte) ="
<< sizeof (int) << std::endl;
std::cout << "bool " << std::numeric_limits<bool>::min() << "-"
<< std::numeric_limits<bool>::max() << "
size (Byte) ="
<< sizeof (bool) << std::endl;

// floating point types
std::cout << "float " << std::numeric_limits<float>::min() <<
"-"
<< std::numeric_limits<float>::max() << " size
(Byte) ="
<< sizeof (float) << std::endl;
std::cout << "double " << std::numeric_limits<double>::min()
<< "-"
<< std::numeric_limits<double>::max() << " size
(Byte) ="
<< sizeof (double) << std::endl;
return 0;
}
  1. Next, build (compile and link) g++ primitives.cpp.
  2. This will produce an executable file with the (default) name of a.out.

How it works...

The output of the preceding program will be something like this:

This represents the minimum and maximum values that a type can represent and the size in bytes for the current platform.

The C++ standard does not define the size of each type, but it does define the minimum width:

  • char: Minimum width = 8
  • short int: Minimum width = 16
  • int: Minimum width = 16
  • long int: Minimum width = 32
  • long int int: Minimum width = 64

This point has huge implications as different platforms can have different sizes and a programmer should cope with this. To help us get some guidance regarding data types, there is the concept of a data model. A data model is a set of choices (a specific size for each type) made by each implementation (the psABI of the architecture that compilers and operating systems adhere to) to define all the primitive data types. The following table shows a subset of various types and data models that exist:

Data type LP32 ILP32 LLP64 LP64
char 8 8 8 8
short int 16 16 16 16
int 16 32 32 32
long 32 32 32 64
pointer 32 32 64 64

The Linux kernel uses the LP64 data model for 64-bit architectures (x86_64).

We briefly touched on the psABI topic (short for platform-specific Application Binary Interfaces (ABIs)). Each architecture (for example, x86_64) has a psABI specification that the OS adheres to. The GNU Compiler Collection (GCC) has to know these details as it has to know the sizes of the primitive types it compiles. The i386.h GCC header file contains the size of the primitive data types for that architecture:

root@453eb8a8d60a:~# uname -a
Linux 453eb8a8d60a 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

The program output shows that the current OS (actually, the Ubuntu image we're running) uses the LP64 data model as expected and that the machine's architecture is x86_64.

There's more...

As we've seen, the C++ standard defines the following primitive data types:

  • Integer: int
  • Character: char
  • Boolean: bool
  • Floating point: float
  • Double floating point: double
  • Void: void
  • Wide character: wchar_t
  • Null pointer: nullptr_­t

Data types can have other information so that their types can be defined:

  • Modifiers: signed, unsigned, long, and short
  • Qualifiers: const and restrict
  • Storage type: auto, static, extern, and mutable

Obviously, not all these additional attributes can be applied to all the types; for example, unsigned cannot be applied to the float and double types (their respective IEEE standards would not allow that).

See also

Lambda expressions

A lambda expression (or lambda function) is a convenient way of defining an anonymous, small, and one-time use function to be used in the place right where it is needed. Lambda is particularly useful with Standard Template Library (STL), as we'll see.

How to do it...

In this section, we'll write some code in order to get familiar with lambda expressions. Although the mechanics are important, pay attention to the code readability with lambda, especially in conjunction with STL. Follow these steps:

  1. In this program, the lambda function gets an integer and prints it to standard output. Let's open a file named lambda_01.cpp and write the following code in it:
#include <iostream>
#include <vector>
#include <algorithm>
int main ()
{
std::vector<int> v {1, 2, 3, 4, 5, 6};
for_each (begin(v), end(v), [](int x) {std::cout << x
<< std::endl;});
return 0;
}
  1. In this second program, the lambda function captures a prefix by reference and prepends it to the integer in the standard output. Let's write the following code in a file called lambda_02.cpp:
#include <iostream>
#include <vector>
#include <algorithm>
int main ()
{
std::vector<int> v {1, 2, 3, 4, 5, 6};
std::string prefix ("0");
for_each (begin(v), end(v), [&prefix](int x) {std::cout
<< prefix << x << std::endl;});
return 0;
}
  1. Finally, we compile it with g++ lambda_02.cpp.

How it works...

In the first example, the lambda function just gets an integer as input and prints it. Note that the code is concise and readable. Lambda can capture the variables in scope by reference, &, or by value, =.

The output of the second program is as follows:

In the second example, the lambda captures the variable prefix by reference, making it visible to the lambda. Here, we captured the prefix variable by reference, but we might have captured any of the following:

  • All the variables by reference [&]
  • All the variables by value [=]
  • Specifying what variables to capture and how to capture them [&var1, =var2]

There are cases where we have to be explicit about the type to return, as in this case:

[](int x) -> std::vector<int>{
if (x%2)
return {1, 2};
else
return {3, 4};
});

The -> std::vector<int> operator, called trailing return type, tells the compiler that this lambda will return a vector of integers.

There's more...

Lambda can be decomposed into six parts:

  1. Capture clause: []
  2. Parameter list: ()
  3. Mutable specification: mutable
  4. Exception specification: noexcept
  5. Trailing return type: -> type
  6. Body: {}

Here, 1, 2, and 6 are mandatory.

Although optional, mutable specification and exception specification are worth having a look at as they might be handy in some circumstances. The mutable specification allows a by-value parameter to be modified by the body of the lambda. A variable in the parameter list is typically captured const-by-value, so the mutable specification just removes this restriction. The second case is the exception specification, which we can use to specify the exceptions the lambda might throw.

See also

The books Effective Modern C++ by Scott Meyers and The C++ Programming Language by Bjarne Stroustrup cover these topics in great detail.

Automatic type deduction and decltype

C++ offers two mechanisms for deducting types from an expression: auto and decltype(). auto is used to deduce a type from its initializer, while decltype() is used to deduce a type for more complex cases. This recipe will show examples of how to use both.

How to do it...

It might be handy (and it actually is) to avoid explicitly specifying the type of variable that will be used, especially when it is particularly long and used very locally:

  1. Let's start with a typical example:
std::map<int, std::string> payslips;
// ...
for (std::map<int,
std::string>::const_iterator iter = payslips.begin();
iter !=payslips.end(); ++iter)
{
// ...
}
  1. Now, let's rewrite it with auto:
std::map<int, std::string> payslips;
// ...
for (auto iter = payslips.begin(); iter !=payslips.end(); ++iter)
{
// ...
}
  1. Let's look at another example:
auto speed = 123;         // speed is an int
auto height = calculate (); // height will be of the
// type returned by calculate()

decltype() is another mechanism offered by C++ that can deduce the type of expression when the expression is more complex than the auto case.

  1. Let's look at this using an example:
decltype(a) y = x + 1;  // deducing the type of a
decltype(str->x) y; // deducing the type of str->x, where str is
// a struct and x
// an int element of that struct

Could we use auto instead of decltype() in these two examples? We'll take a look in the next section.

How it works...

The first example with auto shows that the type is deduced, at compile time, from the right-hand parameter. auto is used in simple cases.

decltype() deduces the type of expression. In the example, it defines the y variable so that it's the same type as a. As you can imagine, this would not be possible with auto. Why? This is pretty simple: decltype() tells the compiler to define a variable of a specific type; in the first example, y is a variable with the same type as a. With auto, the type is deduced automatically.

We should use auto and decltype() anytime we don't have to explicitly specify the type of a variable; for example, when we need a double type (and not a float). It's worth mentioning that both auto and decltype() deduct types of expressions that are already known to the compiler, so they are not runtime mechanisms.

There's more...

There is a specific case that must be mentioned. When auto uses {} (uniform initializers) for type deduction, it can cause some headaches (or at least behaviors that we wouldn't expect). Let's look at an example:

auto fuelLevel {0, 1, 2, 3, 4, 5};

In this case, the type that's being deduced is initializer_list<T> and not an array of integers, as we could expect.

See also

The books Effective Modern C++ by Scott Meyers and The C++ Programming Language by Bjarne Stroustrup cover these topics in great detail.

Learning how atomic works

Traditionally, C and C++ have a long tradition of portable code for system programming. The atomic feature that was introduced in the C++11 standard reinforces this by adding, natively, the guarantee that an operation is seen as atomic by other threads. Atomic is a template, such as template <class T> struct atomic; or template <class T> struct atomic<T*>;. C++20 has added shared_ptr and weak_ptr to T and T*. Any operation that's performed on the atomic variable is now protected from other threads.

How to do it...

std::atomic is an important aspect of modern C++ for dealing with concurrency. Let's write some code to master the concept:

  1. The first snippet of code shows the basics of atomic operations. Let's write this now:
std::atomic<int> speed (0);         // Other threads have access to the speed variable
auto currentSpeed = speed.load(); // default memory order: memory_order_seq_cst
  1. In this second program, we can see that the is_lock_free() method returns true if the implementation is lock-free or if it has been implemented using a lock. Let's write this code:
#include <iostream>
#include <utility>
#include <atomic>
struct MyArray { int z[50]; };
struct MyStr { int a, b; };
int main()
{
std::atomic<MyArray> myArray;
std::atomic<MyStr> myStr;
std::cout << std::boolalpha
<< "std::atomic<myArray> is lock free? "
<< std::atomic_is_lock_free(&myArray) << std::endl
<< "std::atomic<myStr> is lock free? "
<< std::atomic_is_lock_free(&myStr) << std::endl;
}
  1. Let's compile the program. When doing so, you may need to add the atomic library to g++ (due to a GCC bug) with g++ atomic.cpp -latomic.

How it works...

std::atomic<int> speed (0); defines a speed variable as an atomic integer. Although the variable will be atomic, this initialization is not atomic! Instead, the following code: speed +=10; atomically increases the speed of 10. This means that there will not be race conditions. By definition, a race condition happens when among the threads accessing a variable, at least 1 is a writer.

The std::cout << "current speed is: " << speed; instruction reads the current value of the speed automatically. Pay attention to the fact that reading the value from speed is atomic but what happens next is not atomic (that is, printing it through cout). The rule is that read and write are atomic but the surrounding operations are not, as we've seen.

The output of the second program is as follows:

The basic operations for atomic are load, store, swap, and cas (short for compare and swap), which are available on all types of atomics. Others are available, depending on the types (for example, fetch_add).

One question remains open, though. How come myArray uses locks and myStr is lock-free? The reason is simple: C++ provides a lock-free implementation for all the primitive types, and the variables inside MyStr are primitive types. A user will set myStr.a and myStr.b. MyArray, on the other hand, is not a fundamental type, so the underlying implementation will use locks.

The standard guarantee is that for each atomic operation, every thread will make progress. One important aspect to keep in mind is that the compiler makes code optimizations quite often. The use of atomics imposes restrictions on the compiler regarding how the code can be reordered. An example of a restriction is that no code that preceded the write of an atomic variable can be moved after the atomic write.

There's more...

In this recipe, we've used the default memory model called memory_order_seq_cst. Some other memory models that are available are:

  • memory_order_relaxed: Only the current operation atomicity is guaranteed. That is, there are no guarantees on how memory accesses in different threads are ordered with respect to the atomic operation.
  • memory_order_consume: The operation is ordered to happen once all accesses to memory in the releasing thread that carry a dependency on the releasing operation have happened.
  • memory_order_acquire: The operation is ordered to happen once all accesses to memory in the releasing thread have happened.
  • memory_order_release: The operation is ordered to happen before a consume or acquire operation.
  • memory_order_seq_cst: The operation is sequentially consistent ordered.

See also

The books Effective Modern C++ by Scott Meyers and The C++ Programming Language by Bjarne Stroustrup cover these topics in great detail. Furthermore, the Atomic Weapons talk from Herb Sutter, freely available on YouTube (https://www.youtube.com/watch?v=A8eCGOqgvH4), is a great introduction.

Learning how nullptr works

Before C++11, the NULL identifier was meant to be used for pointers. In this recipe, we'll see why this was a problem and how C++11 solved it.

How to do it...

To understand why nullptr is important, let's look at the problem with NULL:

  1. Let's write the following code:
bool speedUp (int speed);
bool speedUp (char* speed);
int main()
{
bool ok = speedUp (NULL);
}
  1. Now, let's rewrite the preceding code using nullptr:
bool speedUp (int speed);
bool speedUp (char* speed);
int main()
{
bool ok = speedUp (nullptr);
}

How it works...

The first program might not compile or (if it does) call the wrong method. We would expect it to call bool speedUp (char* speed); instead. The problem with NULL was exactly this: NULL was defined as 0, which is an integer type, and used by the pre-processor (which was replacing all the occurrences of NULL with 0). This is a huge difference as nullptr is now among the C++ primitives types and managed by the compiler.

For the second program, the speedUp (overloaded) method is called with the char* pointer to nullptr. There is no ambiguity here – we're calling the version with the char* type.

There's more...

nullptr represents a pointer that does not point to any object:

int* p = nullptr;

Due to this, there is no ambiguity, which means that readability improves. Another example that improves readability is as follows:

if (x == nullptr) 
{
// ...\
}

This makes the code more readable and clearly indicates that we're comparing a pointer.

See also

The books Effective Modern C++ by Scott Meyers and The C++ Programming Language by Bjarne Stroustrup cover these topics in great detail.

Smart pointers – unique_ptr and shared_ptr

This recipe will show the basic usage of unique_ptr and shared_ptr. These smart pointers are the main helpers for programmers who don't want to deal with memory deallocation manually. Once you've learned how to use them properly, this will save headaches and nights of debugging sessions.

How to do it...

In this section, we'll look at the basic use of two smart pointers, std::unique_ptr and std::shared_ptr:

  1. Let's develop a unique_ptr example by developing the following class:
#include <iostream>
#include <memory>
class CruiseControl
{
public:
CruiseControl()
{
std::cout << "CruiseControl object created" << std::endl;
};
~CruiseControl()
{
std::cout << "CruiseControl object destroyed" << std::endl;
}
void increaseSpeedTo(int speed)
{
std::cout << "Speed at " << speed << std::endl;
};
};
  1. Now, let's develop a main class by calling the preceding class:
int main ()
{
std::cout << "unique_ptr test started" << std::endl;
std::unique_ptr<CruiseControl> cruiseControl =
std::make_unique<CruiseControl>();
cruiseControl->increaseSpeedTo(12);
std::cout << "unique_ptr test finished" << std::endl;
}
  1. Let's compile g++ unique_ptr_01.cpp.
  2. Another example with unique_ptr shows its behavior with arrays. Let's reuse the same class (CruiseControl):
int main ()
{
std::cout << "unique_ptr test started" << std::endl;
std::unique_ptr<CruiseControl[]> cruiseControl =
std::make_unique<CruiseControl[]>(3);
cruiseControl[1].increaseSpeedTo(12);
std::cout << "unique_ptr test finished" << std::endl;
}
  1. Let's see std::shared_ptr in action with a small program:
#include <iostream>
#include <memory>
class CruiseControl
{
public:
CruiseControl()
{
std::cout << "CruiseControl object created" << std::endl;
};
~CruiseControl()
{
std::cout << "CruiseControl object destroyed" << std::endl;
}
void increaseSpeedTo(int speed)
{
std::cout << "Speed at " << speed << std::endl;
};
};

main looks like this:

int main ()
{
std::cout << "shared_ptr test started" << std::endl;
std::shared_ptr<CruiseControl> cruiseControlMaster(nullptr);
{
std::shared_ptr<CruiseControl> cruiseControlSlave =
std::make_shared<CruiseControl>();
cruiseControlMaster = cruiseControlSlave;
}
std::cout << "shared_ptr test finished" << std::endl;
}

The How it works... section will describe these three programs in detail.

How it works...

By running the first unique_ptr program, that is, ./a.out, we get the following output:

unique_ptr is a smart pointer that embodies the concept of unique ownership. Unique ownership, simply put, means that there is one and only one variable that can own a pointer. The first consequence of this concept is that the copy operator is not allowed on two unique pointer variables. Just move is allowed, where the ownership is transferred from one variable to another. The executable that was run shows that the object is deallocated at the end of the current scope (in this case, the main function): CruiseControl object destroyed. The fact that the developer doesn't need to bother remembering to call delete when needed, but still keep control over memory, is one of the main advantages of C++ over garbage collector-based languages.

In the second unique_ptr example, with arrays, there are three objects of the CruiseControl type that have been allocated and then released. For this, the output is as follows:

    The third example shows usage of shared_ptr. The output of the program is as follows:

    The shared_ptr smart pointer represents the concept that an object is being pointed at (that is, by the owner) by more than one variable. In this case, we're talking about shared ownership. It is clear that the rules are different from the unique_ptr case. An object cannot be released until at least one variable is using it. In this example, we defined a cruiseControlMaster variable pointing to nullptr. Then, we defined a block and in that block, we defined another variable: cruiseControlSlave. So far, so good! Then, still inside the block, we assigned the cruiseControlSlave pointer to cruiseControlMaster. At this point, the object allocated has two pointers: cruiseControlMaster and cruiseControlSlave. When this block is closed, the cruiseControlSlave destructor is called but the object is not freed as it is still used by another one: cruiseControlMaster! When the program finishes, we see the shared_ptr test finished log and immediately after the cruiseControlMaster, as it is the only one pointing to the CruiseControl object release, the object and then the constructor is called, as reported in the CruiseControl object destroyed log.

    Clearly, the shared_ptr data type has a concept of reference counting to keep track of the number of pointers. These references are increased during the constructors (not always; the move constructor isn't) and the copy assignment operator and decreased in the destructors.

    Can the reference counting variable be safely increased and decreased? The pointers to the same object might be in different threads, so manipulating this variable might be an issue. This is not an issue as the reference counting variable is atomically managed (that is, it is an atomic variable).

    One last point about the size. unique_ptr is as big as a raw pointer, whereas shared_ptr is typically double the size of unique_ptr because of the reference counting variable.

    There's more...

    See also

    The books Effective Modern C++ by Scott Meyers and The C++ Programming Language by Bjarne Stroustrup cover these topics in great detail.

    Left arrow icon Right arrow icon
    Download code icon Download Code

    Key benefits

    • Learn to apply the latest C++ features (from C++11, 14, 17, and 20) to facilitate systems programming
    • Create robust and concurrent systems that make the most of the available hardware resources
    • Delve into C++ inbuilt libraries and frameworks to design robust systems as per your business needs

    Description

    C++ is the preferred language for system programming due to its efficient low-level computation, data abstraction, and object-oriented features. System programming is about designing and writing computer programs that interact closely with the underlying operating system and allow computer hardware to interface with the programmer and the user. The C++ System Programming Cookbook will serve as a reference for developers who want to have ready-to-use solutions for the essential aspects of system programming using the latest C++ standards wherever possible. This C++ book starts out by giving you an overview of system programming and refreshing your C++ knowledge. Moving ahead, you will learn how to deal with threads and processes, before going on to discover recipes for how to manage memory. The concluding chapters will then help you understand how processes communicate and how to interact with the console (console I/O). Finally, you will learn how to deal with time interfaces, signals, and CPU scheduling. By the end of the book, you will become adept at developing robust systems applications using C++.

    Who is this book for?

    This book is for C++ developers who want to gain practical knowledge of systems programming. Though no experience of Linux system programming is assumed, intermediate knowledge of C++ is necessary.

    What you will learn

    • Get up to speed with the fundamentals including makefile, man pages, compilation, and linking and debugging
    • Understand how to deal with time interfaces, signals, and CPU scheduling
    • Develop your knowledge of memory management
    • Use processes and threads for advanced synchronizations (mutexes and condition variables)
    • Understand interprocess communications (IPC): pipes, FIFOs, message queues, shared memory, and TCP and UDP
    • Discover how to interact with the console (console I/O)
    Estimated delivery fee Deliver to United States

    Economy delivery 10 - 13 business days

    Free $6.95

    Premium delivery 6 - 9 business days

    $21.95
    (Includes tracking information)

    Product Details

    Country selected
    Publication date, Length, Edition, Language, ISBN-13
    Last updated date : Jun 04, 2025
    Publication date : Feb 21, 2020
    Length: 292 pages
    Edition : 1st
    Language : English
    ISBN-13 : 9781838646554
    Category :
    Languages :
    Tools :

    What do you get with Print?

    Product feature icon Instant access to your digital copy whilst your Print order is Shipped
    Product feature icon Paperback book shipped to your preferred address
    Product feature icon Redeem a companion digital copy on all Print orders
    Product feature icon Access this title in our online reader with advanced features
    Product feature icon DRM FREE - Read whenever, wherever and however you want
    Product feature icon AI Assistant (beta) to help accelerate your learning
    OR
    Modal Close icon
    Payment Processing...
    tick Completed

    Shipping Address

    Billing Address

    Shipping Methods
    Estimated delivery fee Deliver to United States

    Economy delivery 10 - 13 business days

    Free $6.95

    Premium delivery 6 - 9 business days

    $21.95
    (Includes tracking information)

    Product Details

    Last updated date : Jun 04, 2025
    Publication date : Feb 21, 2020
    Length: 292 pages
    Edition : 1st
    Language : English
    ISBN-13 : 9781838646554
    Category :
    Languages :
    Tools :

    Packt Subscriptions

    See our plans and pricing
    Modal Close icon
    $19.99 billed monthly
    Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
    Feature tick icon Constantly refreshed with 50+ new titles a month
    Feature tick icon Exclusive Early access to books as they're written
    Feature tick icon Solve problems while you work with advanced search and reference features
    Feature tick icon Offline reading on the mobile app
    Feature tick icon Simple pricing, no contract
    $199.99 billed annually
    Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
    Feature tick icon Constantly refreshed with 50+ new titles a month
    Feature tick icon Exclusive Early access to books as they're written
    Feature tick icon Solve problems while you work with advanced search and reference features
    Feature tick icon Offline reading on the mobile app
    Feature tick icon Choose a DRM-free eBook or Video every month to keep
    Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
    Feature tick icon Exclusive print discounts
    $279.99 billed in 18 months
    Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
    Feature tick icon Constantly refreshed with 50+ new titles a month
    Feature tick icon Exclusive Early access to books as they're written
    Feature tick icon Solve problems while you work with advanced search and reference features
    Feature tick icon Offline reading on the mobile app
    Feature tick icon Choose a DRM-free eBook or Video every month to keep
    Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
    Feature tick icon Exclusive print discounts

    Frequently bought together


    Stars icon
    Total $ 134.97
    C++ System Programming Cookbook
    €29.99
    Expert C++
    €32.99
    Modern C++ Programming Cookbook
    €71.99
    Total $ 134.97 Stars icon

    Table of Contents

    12 Chapters
    Getting Started with System Programming Chevron down icon Chevron up icon
    Revisiting C++ Chevron down icon Chevron up icon
    Dealing with Processes and Threads Chevron down icon Chevron up icon
    Deep Dive into Memory Management Chevron down icon Chevron up icon
    Using Mutexes, Semaphores, and Condition Variables Chevron down icon Chevron up icon
    Pipes, First-In First-Out (FIFO), Message Queues, and Shared Memory Chevron down icon Chevron up icon
    Network Programming Chevron down icon Chevron up icon
    Dealing with Console I/O and Files Chevron down icon Chevron up icon
    Dealing with Time Interfaces Chevron down icon Chevron up icon
    Managing Signals Chevron down icon Chevron up icon
    Scheduling Chevron down icon Chevron up icon
    Other Books You May Enjoy Chevron down icon Chevron up icon

    Customer reviews

    Rating distribution
    Full star icon Full star icon Full star icon Half star icon Empty star icon 3.8
    (4 Ratings)
    5 star 50%
    4 star 25%
    3 star 0%
    2 star 0%
    1 star 25%
    Scott Hutchinson Mar 16, 2020
    Full star icon Full star icon Full star icon Full star icon Full star icon 5
    I had the privilege to be a technical reviewer on this book. The C++ System Programming Cookbook provides a detailed, hands-on introduction to many critical system programming tasks on the Linux operating system. This book is particularly helpful for those C++ programmers who are not very familiar with Linux. In addition, all the code samples for the book are available in a Docker image with Ubuntu 19.04 and g++ 8.3.0 installed, which provides a side benefit for the reader to learn how to develop and debug C++ in a Docker container. While some of the tasks are demonstrated using POSIX APIs in C/C++, most of the examples are written in modern C++, taking advantage of some features of C++11, such as the std::chrono namespace and the std::unique_lock, std::promise, and std::future classes. Even some C++17 features are included, such as the std::filesystem namespace. Whether you are familiar with Linux or not, reading this concise book and running all the code samples will teach you the fundamental techniques you need to develop robust systems applications using C++.
    Amazon Verified review Amazon
    Jim Ledin May 14, 2022
    Full star icon Full star icon Full star icon Full star icon Full star icon 5
    I really like how the book starts with an explanation of the essential features of the Linux architecture and makes no assumption of prior Linux experience. This provides a strong foundation for later chapters that delve into the details of programming Linux at the system level.I also like the thorough introduction to C++ 11 through 20. This is a great help to those of us with experience in C++ from years past, but who haven't kept up with the recent (and exciting!) language enhancements. This includes things like lambda expressions, automatic type deduction, smart pointers, and support for concurrency.Each topic covered in the book follows the pattern of introducing the concept, demonstrating how to implement it, and explaining how it works. Additional information is provided on more advanced uses of the topic and sources for further information.This book is a valuable asset for anyone with a need to use the modern features of C++ in the context of system programming for Linux and other POSIX-compliant operating systems. Highly recommended!
    Amazon Verified review Amazon
    Karen Mar 19, 2021
    Full star icon Full star icon Full star icon Full star icon Empty star icon 4
    I've enjoyed a lot the good overview the author gave by covering (almost) all the aspects of the system programming. The examples (although basic) help to have a good grasp of the topic.
    Amazon Verified review Amazon
    S. Ghiassy Mar 12, 2021
    Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
    i only found maybe 10 pages of this book useful and taught me something the rest is just crap. By its structure is obvious that the author just wanted to make pages by being repetitive about the running instruction. Total waste of money.
    Amazon Verified review Amazon
    Get free access to Packt library with over 7500+ books and video courses for 7 days!
    Start Free Trial

    FAQs

    What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

    When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

    What is the delivery time and cost of print book? Chevron down icon Chevron up icon

    Shipping Details

    USA:

    '

    Economy: Delivery to most addresses in the US within 10-15 business days

    Premium: Trackable Delivery to most addresses in the US within 3-8 business days

    UK:

    Economy: Delivery to most addresses in the U.K. within 7-9 business days.
    Shipments are not trackable

    Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
    Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

    EU:

    Premium: Trackable delivery to most EU destinations within 4-9 business days.

    Australia:

    Economy: Can deliver to P. O. Boxes and private residences.
    Trackable service with delivery to addresses in Australia only.
    Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
    Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

    Premium: Delivery to addresses in Australia only
    Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

    India:

    Premium: Delivery to most Indian addresses within 5-6 business days

    Rest of the World:

    Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

    Asia:

    Premium: Delivery to most Asian addresses within 5-9 business days

    Disclaimer:
    All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


    Unfortunately, due to several restrictions, we are unable to ship to the following countries:

    1. Afghanistan
    2. American Samoa
    3. Belarus
    4. Brunei Darussalam
    5. Central African Republic
    6. The Democratic Republic of Congo
    7. Eritrea
    8. Guinea-bissau
    9. Iran
    10. Lebanon
    11. Libiya Arab Jamahriya
    12. Somalia
    13. Sudan
    14. Russian Federation
    15. Syrian Arab Republic
    16. Ukraine
    17. Venezuela
    What is custom duty/charge? Chevron down icon Chevron up icon

    Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

    Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

    The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

    List of EU27 countries: www.gov.uk/eu-eea:

    A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

    How do I know my custom duty charges? Chevron down icon Chevron up icon

    The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

    For example:

    • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
    • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
    How can I cancel my order? Chevron down icon Chevron up icon

    Cancellation Policy for Published Printed Books:

    You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

    Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

    What is your returns and refunds policy? Chevron down icon Chevron up icon

    Return Policy:

    We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

    1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
    2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
    3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
    4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
    5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
    6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

    On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

    What tax is charged? Chevron down icon Chevron up icon

    Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

    What payment methods can I use? Chevron down icon Chevron up icon

    You can pay with the following card types:

    1. Visa Debit
    2. Visa Credit
    3. MasterCard
    4. PayPal
    What is the delivery time and cost of print books? Chevron down icon Chevron up icon

    Shipping Details

    USA:

    '

    Economy: Delivery to most addresses in the US within 10-15 business days

    Premium: Trackable Delivery to most addresses in the US within 3-8 business days

    UK:

    Economy: Delivery to most addresses in the U.K. within 7-9 business days.
    Shipments are not trackable

    Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
    Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

    EU:

    Premium: Trackable delivery to most EU destinations within 4-9 business days.

    Australia:

    Economy: Can deliver to P. O. Boxes and private residences.
    Trackable service with delivery to addresses in Australia only.
    Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
    Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

    Premium: Delivery to addresses in Australia only
    Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

    India:

    Premium: Delivery to most Indian addresses within 5-6 business days

    Rest of the World:

    Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

    Asia:

    Premium: Delivery to most Asian addresses within 5-9 business days

    Disclaimer:
    All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


    Unfortunately, due to several restrictions, we are unable to ship to the following countries:

    1. Afghanistan
    2. American Samoa
    3. Belarus
    4. Brunei Darussalam
    5. Central African Republic
    6. The Democratic Republic of Congo
    7. Eritrea
    8. Guinea-bissau
    9. Iran
    10. Lebanon
    11. Libiya Arab Jamahriya
    12. Somalia
    13. Sudan
    14. Russian Federation
    15. Syrian Arab Republic
    16. Ukraine
    17. Venezuela
    Modal Close icon
    Modal Close icon