{"id":191,"date":"2023-04-06T09:09:47","date_gmt":"2023-04-06T09:09:47","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=191"},"modified":"2023-08-23T16:22:30","modified_gmt":"2023-08-23T16:22:30","slug":"modern-cpp-multithreading-techniques","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/","title":{"rendered":"Modern C++ Multithreading Techniques: Unlocking the Power of Concurrent Programming"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Concurrency and multithreading have become increasingly important in the world of software development as the need to leverage multiple cores and processors for improved performance and efficiency grows. With the advent of modern C++, developers now have access to a robust set of multithreading tools and techniques that can help them create more efficient and powerful applications. This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17 standards. Our target audience is experienced developers who are looking to expand their knowledge of concurrent programming in C++.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Overview of C++ Multithreading Concepts<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1.1 Threads<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A thread is the smallest unit of execution within a process. Multithreading allows multiple threads to run concurrently within a single process, sharing resources such as memory and file handles. Threads within a process can run concurrently on different CPU cores, enabling efficient parallel execution of tasks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.2 Concurrency vs. Parallelism<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Concurrency refers to the ability of a program to manage multiple tasks simultaneously, while parallelism is the actual simultaneous execution of these tasks. Concurrency can be achieved without parallelism, as in the case of a single-core processor, where tasks are interleaved.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.3 Synchronization<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Thread synchronization is crucial for preventing data races and ensuring the correctness of multithreaded programs. This can be achieved using various techniques, such as mutexes, locks, and condition variables.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. C++11: Standard Threading Library<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">C++11 introduced the standard threading library, which provided an extensive set of tools and utilities to manage threads, synchronization primitives, and thread-local storage.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 Creating and Managing Threads<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong><code>std::thread<\/code><\/strong> class in C++11 allows for the creation and management of threads. To create a new thread, simply instantiate the <strong><code>std::thread<\/code><\/strong> object with a function or a callable object. The newly created thread starts executing the provided function. To wait for the completion of a thread, use the <strong><code>join()<\/code><\/strong> method.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;thread&gt;<\/span><\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">my_function<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Hello from my_function!\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">t<\/span><span class=\"hljs-params\">(my_function)<\/span><\/span>;\n  t.join();\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">2.2 Synchronization Primitives<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">2.2.1 Mutexes<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong><code>mutex<\/code><\/strong> (short for &#8220;mutual exclusion&#8221;) is a synchronization primitive used to ensure that only one thread can access a shared resource at a time. In C++11, the <strong><code>std::mutex<\/code><\/strong> class provides a basic <strong><code>mutex<\/code><\/strong> implementation.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;mutex&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;thread&gt;<\/span><\/span>\n\n<span class=\"hljs-built_in\">std<\/span>::mutex mtx;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">print_hello<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::unique_lock&lt;<span class=\"hljs-built_in\">std<\/span>::mutex&gt; <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(mtx)<\/span><\/span>;\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Hello, world!\"<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n  lock.unlock();\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">t1<\/span><span class=\"hljs-params\">(print_hello)<\/span><\/span>;\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">t2<\/span><span class=\"hljs-params\">(print_hello)<\/span><\/span>;\n  t1.join();\n  t2.join();\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">2.2.2 Locks<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">C++11 provides various lock classes, such as <strong><code>std::lock_guard<\/code><\/strong> and <strong><code>std::unique_lock<\/code><\/strong>, which can be used to manage the ownership and locking of mutexes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.2.3 Condition Variables<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">A condition variable is a synchronization primitive used to block a thread until a particular condition is met. C++11 provides the <code><strong>std::condition_variable<\/strong><\/code> class for this purpose.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.3 Thread-Local Storage<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Thread-local storage (TLS) allows each thread to have its own instance of a variable, ensuring that the value of the variable is not shared between threads. C++11 introduces the <strong><code>thread_local<\/code><\/strong> keyword for defining thread-local variables.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;thread&gt;<\/span><\/span>\n\n<span class=\"hljs-keyword\">thread_local<\/span> <span class=\"hljs-keyword\">int<\/span> counter = <span class=\"hljs-number\">0<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">increment_counter<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  ++counter;\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Counter: \"<\/span> &lt;&lt; counter &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">t1<\/span><span class=\"hljs-params\">(increment_counter)<\/span><\/span>;\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">t2<\/span><span class=\"hljs-params\">(increment_counter)<\/span><\/span>;\n  t1.join();\n  t2.join();\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">3. C++14 and C++17: Enhancements and New Features<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">C++14 and C++17 brought several improvements and new features to the world of multithreading, making it even more powerful and easier to use.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 C++14: Shared Locks<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">C++14 introduced the <strong><code>std::shared_timed_mutex<\/code><\/strong> and <strong><code>std::shared_lock<\/code><\/strong> classes, allowing for shared ownership of a <strong><code>mutex<\/code><\/strong>. This is particularly useful when multiple threads need to read a shared resource but only one thread can modify it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;shared_mutex&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;thread&gt;<\/span><\/span>\n\n<span class=\"hljs-built_in\">std<\/span>::shared_timed_mutex mtx;\n<span class=\"hljs-keyword\">int<\/span> shared_data = <span class=\"hljs-number\">0<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">reader<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::shared_lock&lt;<span class=\"hljs-built_in\">std<\/span>::shared_timed_mutex&gt; <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(mtx)<\/span><\/span>;\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Reader: shared_data = \"<\/span> &lt;&lt; shared_data &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">writer<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::unique_lock&lt;<span class=\"hljs-built_in\">std<\/span>::shared_timed_mutex&gt; <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(mtx)<\/span><\/span>;\n  ++shared_data;\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Writer: shared_data = \"<\/span> &lt;&lt; shared_data &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">r1<\/span><span class=\"hljs-params\">(reader)<\/span><\/span>;\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">r2<\/span><span class=\"hljs-params\">(reader)<\/span><\/span>;\n  <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::thread <span class=\"hljs-title\">w1<\/span><span class=\"hljs-params\">(writer)<\/span><\/span>;\n  r1.join();\n  r2.join();\n  w1.join();\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">3.2 C++17: Parallel Algorithms<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">C++17 introduced parallel algorithms as part of the standard library, allowing developers to leverage parallelism with ease. These algorithms operate on standard containers and are designed to automatically parallelize their execution when possible. Developers can specify the desired level of parallelism using execution policies, such as <strong><code>std::execution::seq<\/code><\/strong>, <strong><code>std::execution::par<\/code><\/strong>, and <strong><code>std::execution::par_unseq<\/code><\/strong>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;algorithm&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;execution&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;vector&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; data{<span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">8<\/span>, <span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">6<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">7<\/span>};\n  <span class=\"hljs-built_in\">std<\/span>::sort(<span class=\"hljs-built_in\">std<\/span>::execution::par, data.begin(), data.end());\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">auto<\/span>&amp; value : data) {\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; value &lt;&lt; <span class=\"hljs-string\">\" \"<\/span>;\n  }\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">4. Best Practices for Modern C++ Multithreading<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">4.1 Avoid Global Variables<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Global variables can lead to data races and synchronization issues. Whenever possible, use local variables or thread-local storage instead.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.2 Minimize Lock Contention<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Lock contention occurs when multiple threads compete for the same lock. To minimize lock contention, minimize the time spent holding locks and avoid nested locking.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.3 Use Fine-Grained Locks<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of using a single lock for an entire data structure, use multiple fine-grained locks to protect smaller parts of the structure. This allows for greater concurrency and reduces lock contention.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.4 Use Lock-Free Data Structures<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Lock-free data structures can provide better performance and scalability in certain scenarios. Consider using lock-free data structures, such as those provided by the C++ Concurrency TS, when appropriate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example Exercise: Multithreaded Web Crawler<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective<\/strong>: Create a simple multithreaded web crawler that downloads and extracts URLs from web pages using modern C++ multithreading techniques.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Task Description<\/strong>: Implement a web crawler that starts with a seed URL, fetches the content of the page, extracts all the URLs present in the page, and continues crawling the extracted URLs. The crawler should use multiple threads to download and process web pages concurrently. Additionally, the crawler should store visited URLs to avoid revisiting the same pages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To achieve this, we&#8217;ll use the following libraries:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>libcurl<\/strong> for fetching web pages.<\/li>\n\n\n\n<li><strong>htmlcxx<\/strong> for parsing HTML and extracting URLs.<\/li>\n\n\n\n<li>C++ standard threading library for multithreading.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Source code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;iostream&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;string&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;unordered_set&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;vector&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;queue&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;mutex&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;thread&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;condition_variable&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;curl\/curl.h&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;htmlcxx\/html\/ParserDom.h&gt;<\/span><\/span>\n\n<span class=\"hljs-comment\">\/\/ Global variables<\/span>\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">unordered_set<\/span>&lt;<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt; visited_urls;\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">queue<\/span>&lt;<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt; urls_to_visit;\n<span class=\"hljs-built_in\">std<\/span>::mutex mtx;\n<span class=\"hljs-built_in\">std<\/span>::condition_variable cv;\n\n<span class=\"hljs-comment\">\/\/ CURL write callback to store fetched content<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">size_t<\/span> <span class=\"hljs-title\">write_callback<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">void<\/span>* contents, <span class=\"hljs-keyword\">size_t<\/span> size, <span class=\"hljs-keyword\">size_t<\/span> nmemb, <span class=\"hljs-keyword\">void<\/span>* userp)<\/span> <\/span>{\n    ((<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>*)userp)-&gt;append((<span class=\"hljs-keyword\">char<\/span>*)contents, size * nmemb);\n    <span class=\"hljs-keyword\">return<\/span> size * nmemb;\n}\n\n<span class=\"hljs-comment\">\/\/ Fetch the content of the given URL<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> <span class=\"hljs-title\">fetch_url<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&amp; url)<\/span> <\/span>{\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> content;\n    CURL* curl = curl_easy_init();\n\n    <span class=\"hljs-keyword\">if<\/span> (curl) {\n        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());\n        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);\n        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &amp;content);\n        curl_easy_perform(curl);\n        curl_easy_cleanup(curl);\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> content;\n}\n\n<span class=\"hljs-comment\">\/\/ Extract URLs from the content of a web page<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt; <span class=\"hljs-title\">extract_urls<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&amp; content)<\/span> <\/span>{\n    htmlcxx::HTML::ParserDom parser;\n    tree&lt;htmlcxx::HTML::Node&gt; dom = parser.parseTree(content);\n\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt; urls;\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">auto<\/span> it = dom.begin(); it != dom.end(); ++it) {\n        <span class=\"hljs-keyword\">if<\/span> (it-&gt;tagName() == <span class=\"hljs-string\">\"a\"<\/span>) {\n            it-&gt;parseAttributes();\n            <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> url = it-&gt;attribute(<span class=\"hljs-string\">\"href\"<\/span>).second;\n            <span class=\"hljs-keyword\">if<\/span> (!url.empty()) {\n                urls.push_back(url);\n            }\n        }\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> urls;\n}\n\n<span class=\"hljs-comment\">\/\/ Crawl function that runs in multiple threads<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">crawl<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">while<\/span> (<span class=\"hljs-literal\">true<\/span>) {\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::unique_lock&lt;<span class=\"hljs-built_in\">std<\/span>::mutex&gt; <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(mtx)<\/span><\/span>;\n        cv.wait(lock, &#91;]{ <span class=\"hljs-keyword\">return<\/span> !urls_to_visit.empty(); });\n\n        <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> url = urls_to_visit.front();\n        urls_to_visit.pop();\n        lock.unlock();\n\n        <span class=\"hljs-keyword\">if<\/span> (visited_urls.find(url) == visited_urls.end()) {\n            <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> content = fetch_url(url);\n            <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt; extracted_urls = extract_urls(content);\n\n            lock.lock();\n            visited_urls.insert(url);\n            <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">auto<\/span>&amp; extracted_url : extracted_urls) {\n                <span class=\"hljs-keyword\">if<\/span> (visited_urls.find(extracted_url) == visited_urls.end()) {\n                    urls_to_visit.push(extracted_url);\n                }\n            }\n            lock.unlock();\n\n            <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-string\">\"Visited URL: \"<\/span> &lt;&lt; url &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n        }\n\n        cv.notify_one();\n    }\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ Initialize CURL<\/span>\n    curl_global_init(CURL_GLOBAL_DEFAULT);\n\n    <span class=\"hljs-comment\">\/\/ Seed URL<\/span>\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span> seed_url = <span class=\"hljs-string\">\"https:\/\/www.example.com\"<\/span>;\n    urls_to_visit.push(seed_url);\n\n    <span class=\"hljs-comment\">\/\/ Number of threads for the web crawler<\/span>\n    <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">unsigned<\/span> <span class=\"hljs-keyword\">int<\/span> num_threads = <span class=\"hljs-number\">4<\/span>;\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-built_in\">std<\/span>::thread&gt; threads;\n\n    <span class=\"hljs-comment\">\/\/ Create and start the threads<\/span>\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">unsigned<\/span> <span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; num_threads; ++i) {\n        threads.emplace_back(crawl);\n    }\n\n    <span class=\"hljs-comment\">\/\/ Set a limit for the number of visited URLs<\/span>\n    <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">size_t<\/span> max_visited_urls = <span class=\"hljs-number\">100<\/span>;\n\n    <span class=\"hljs-comment\">\/\/ Wait for the crawler to finish<\/span>\n    <span class=\"hljs-keyword\">while<\/span> (<span class=\"hljs-literal\">true<\/span>) {\n        <span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::unique_lock&lt;<span class=\"hljs-built_in\">std<\/span>::mutex&gt; <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(mtx)<\/span><\/span>;\n        cv.wait(lock, &#91;&amp;]{ <span class=\"hljs-keyword\">return<\/span> visited_urls.size() &gt;= max_visited_urls; });\n        <span class=\"hljs-keyword\">break<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ Stop the threads and wait for them to finish<\/span>\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">auto<\/span>&amp; thread : threads) {\n        <span class=\"hljs-keyword\">if<\/span> (thread.joinable()) {\n            thread.detach();\n        }\n    }\n\n    <span class=\"hljs-comment\">\/\/ Cleanup CURL<\/span>\n    curl_global_cleanup();\n\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This example demonstrates a multithreaded web crawler that fetches web pages, extracts URLs, and continues crawling the extracted URLs. The program uses the C++ standard threading library to manage threads, the libcurl library to fetch web pages, and the <strong>htmlcxx<\/strong> library to parse HTML and extract URLs. To keep track of visited URLs and URLs to be visited, the crawler uses a <strong><code>std::unordered_set<\/code><\/strong> and a <code><strong>std::queue<\/strong><\/code>, respectively, with proper synchronization using <strong><code>std::mutex<\/code><\/strong> and <strong><code>std::condition_variable<\/code><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that this example is for illustrative purposes and is not intended for use in production environments. A production-ready web crawler would require proper error handling, URL normalization, URL filtering, and adherence to the robots.txt standard, among other considerations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Concurrency and multithreading have become increasingly important in the world of software development as the need to leverage multiple cores and processors for improved performance and efficiency grows. With the advent of modern C++, developers now have access to a robust set of multithreading tools and techniques that can help them create more efficient and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[9,4],"tags":[],"class_list":["post-191","post","type-post","status-publish","format-standard","category-cplusplus","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Modern C++ Multithreading Techniques<\/title>\n<meta name=\"description\" content=\"This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Modern C++ Multithreading Techniques\" \/>\n<meta property=\"og:description\" content=\"This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-06T09:09:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T16:22:30+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Modern C++ Multithreading Techniques: Unlocking the Power of Concurrent Programming\",\"datePublished\":\"2023-04-06T09:09:47+00:00\",\"dateModified\":\"2023-08-23T16:22:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/\"},\"wordCount\":891,\"commentCount\":0,\"articleSection\":[\"C++\",\"Programming Languages\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/\",\"name\":\"Modern C++ Multithreading Techniques\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2023-04-06T09:09:47+00:00\",\"dateModified\":\"2023-08-23T16:22:30+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/modern-cpp-multithreading-techniques\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"C++\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/cplusplus\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Modern C++ Multithreading Techniques: Unlocking the Power of Concurrent Programming\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Modern C++ Multithreading Techniques","description":"This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/","og_locale":"en_US","og_type":"article","og_title":"Modern C++ Multithreading Techniques","og_description":"This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17","og_url":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/","article_published_time":"2023-04-06T09:09:47+00:00","article_modified_time":"2023-08-23T16:22:30+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Modern C++ Multithreading Techniques: Unlocking the Power of Concurrent Programming","datePublished":"2023-04-06T09:09:47+00:00","dateModified":"2023-08-23T16:22:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/"},"wordCount":891,"commentCount":0,"articleSection":["C++","Programming Languages"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/","url":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/","name":"Modern C++ Multithreading Techniques","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2023-04-06T09:09:47+00:00","dateModified":"2023-08-23T16:22:30+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"This article aims to delve deep into modern C++ multithreading techniques, focusing on the features introduced by the C++11, C++14, and C++17","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/modern-cpp-multithreading-techniques\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"C++","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/cplusplus\/"},{"@type":"ListItem","position":4,"name":"Modern C++ Multithreading Techniques: Unlocking the Power of Concurrent Programming"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=191"}],"version-history":[{"count":5,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/191\/revisions"}],"predecessor-version":[{"id":747,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/191\/revisions\/747"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}