{"id":478,"date":"2017-06-29T08:01:22","date_gmt":"2017-06-29T08:01:22","guid":{"rendered":"http:\/\/imalogic.com\/blog\/?p=478"},"modified":"2018-03-14T09:57:51","modified_gmt":"2018-03-14T09:57:51","slug":"c-multi-threading-support","status":"publish","type":"post","link":"https:\/\/imalogic.com\/blog\/2017\/06\/29\/c-multi-threading-support\/","title":{"rendered":"C++ Multi-threading support"},"content":{"rendered":"<body><p>One major new feature in the C++0x standard is multi-threading support. Prior to C++0x, any multi-threading support in your C++ compiler has been provided as an extension to the C++ standard, which has meant that the details of that support varies between compilers and platforms. However, with the new standard, all compilers will have to conform to the same memory model and provide the same facilities for multi-threading (though implementors are still free to provide additional extensions). What does this mean for you? It means you\u2019ll be able to port multi-threaded code between compilers and platforms with much reduced cost. This will also reduce the number of different APIs and syntaxes you\u2019ll have to know when writing for multiple platforms.<\/p>\n<p>The core of the new thread library is the std::thread class, which manages a thread of execution, so let\u2019s start by looking at that.<\/p>\n<p><strong>Launching Threads<\/strong><br>\nYou start a new thread by constructing an instance of std::thread with a function. This function is then used as the entry point for the new thread, and once that function returns, the thread is finished:<\/p>\n<p><code>void do_work();<br>\nstd::thread t(do_work);<br>\n<\/code><\/p>\n<p>This is just like the thread-creation APIs we\u2019re all used to\u2014but there\u2019s a crucial difference: This is C++, so we\u2019re not restricted to functions. Just like many of the algorithms in the Standard C++ Library, std::thread will accept an object of a type that implements the function call operator (<span class=\"pf\">operator()<\/span>), as well as ordinary functions:<\/p>\n<p><code><br>\nclass do_work<br>\n{<br>\npublic:<br>\nvoid operator()();<br>\n};<\/code><\/p>\n<p>do_work dw;<br>\nstd::thread t(dw);<\/p>\n<p>It\u2019s important to note that this actually copies the supplied object into the thread. If you really want to use the object you supplied (in which case, you\u2019d better make sure that it doesn\u2019t get destroyed before the thread finishes), you can do so by wrapping it in\u00a0<span class=\"pf\">std::ref<\/span>:<\/p>\n<p><code><br>\ndo_work dw;<br>\nstd::thread t(std::ref(dw));<br>\n<\/code><\/p>\n<p>Most thread creation APIs allow you to pass a single parameter to your newly created thread, typically a\u00a0<span class=\"pf\">long<\/span>\u00a0or a\u00a0<span class=\"pf\">void*<\/span>.\u00a0<span class=\"pf\">std::thread<\/span>\u00a0allows arguments too, but you can pass any number, of (almost) any type. Yes, you read that right: any number of arguments. The constructor uses C++0x\u2019s new\u00a0<a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2007\/n2242.pdf\" target=\"_blank\" rel=\"noopener\">variadic template facility<\/a>\u00a0to allow a variable number of arguments like the old \u2026 varargs syntax, but in a type-safe manner.<\/p>\n<p>You can now pass objects of any copyable type as arguments to the thread function:<\/p>\n<p><code><br>\nvoid do_more_work(int i,std::string s,std::vector&lt;double&gt; v);<br>\nstd::thread<br>\nt(do_more_work,42,\"hello\",std::vector&lt;double&gt;(23,3.141));<br>\n<\/code><\/p>\n<p>Just as with the function object itself, the arguments are copied into the thread before the function is invoked, so if you want to pass a reference you need to wrap the argument in\u00a0<span class=\"pf\">std::ref<\/span>:<\/p>\n<p><code><br>\nvoid foo(std::string&amp;);<br>\nstd::string s;<br>\nstd::thread t(foo,std::ref(s));<br>\n<\/code><\/p>\n<p>OK, that\u2019s enough about launching threads. What about waiting for the thread to finish? The C++ Standard calls that \u201cjoining\u201d with the thread (after the POSIX terminology), and you do that with the\u00a0<span class=\"pf\">join()<\/span>\u00a0member function:<\/p>\n<p><code><br>\nvoid do_work();<br>\nstd::thread t(do_work);<br>\nt.join();<br>\n<\/code><\/p>\n<p>If you\u2019re not planning on joining with your thread, just destroy the thread object or call\u00a0<span class=\"pf\">detach()<\/span>:<\/p>\n<p><code><br>\nvoid do_work();<br>\nstd::thread t(do_work);<br>\nt.detach();<br>\n<\/code><\/p>\n<p>Now, it\u2019s very well launching all these threads, but if you\u2019re going to share data you\u2019d better protect it. The new C++ Standard Library provides facilities for that, too.<\/p>\n<p>\u00a0<\/p>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>One major new feature in the C++0x standard is multi-threading support. Prior to C++0x, any multi-threading support in your C++<\/p>\n","protected":false},"author":1,"featured_media":472,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7],"tags":[],"class_list":["post-478","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-coding"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/06\/cpp_logo.png?fit=360%2C405&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8J21V-7I","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts\/478","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/comments?post=478"}],"version-history":[{"count":1,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts\/478\/revisions"}],"predecessor-version":[{"id":580,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts\/478\/revisions\/580"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/media\/472"}],"wp:attachment":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/media?parent=478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/categories?post=478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/tags?post=478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}