{"id":5533,"date":"2018-10-19T10:08:20","date_gmt":"2018-10-19T10:08:20","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/a-new-thread-with-c-20-std-jthread\/"},"modified":"2023-06-26T11:43:14","modified_gmt":"2023-06-26T11:43:14","slug":"a-new-thread-with-c-20-std-jthread","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/a-new-thread-with-c-20-std-jthread\/","title":{"rendered":"A new Thread with C++20: std::jthread"},"content":{"rendered":"<p>One of the participants in my <a href=\"https:\/\/cppcon.org\/cppcon-2018-program\/\">CppCon 2018<\/a> workshop asked me: &#8220;Can a <span style=\"font-family: courier new, courier;\">std::thread<\/span> be interrupted?&#8221;. No, that was my answer, but this is not correct anymore. With C++20, we might get a <span style=\"font-family: courier new, courier;\">std::jthread.<\/span><\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p>Let me continue my story from the CppCon 2018. During a break from my concurrency workshop, I had a chat with Nicolai (Josuttis). He asked me what I think about the new proposal&nbsp;<a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0660r5.pdf\">P0660: Cooperatively Interruptible Joining Thread. <\/a>At this point, I didn&#8217;t know the proposal. Nicolai is together with Herb Sutter and Anthony Williams one of the authors of the proposal. Today&#8217;s post is about the concurrent future. Here is the big picture to concurrency in current and upcoming C++.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4724\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/04\/timeline.png\" alt=\"timeline\" width=\"600\" height=\"269\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>From the title of the paper <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0660r5.pdf\">Cooperatively Interruptible Joining Thread <\/a>you may guess that the new thread has two new capabilities: interruptable and automatic joining. Let me first write about automatically joining.<a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0660r5.pdf\"> <\/a><\/p>\n<\/p>\n<h2>Automatically joining<\/h2>\n<p>This is the non-intuitive behavior of <span style=\"font-family: courier new, courier;\">std::thread.<\/span> If a <span style=\"font-family: courier new, courier;\">std::thread<\/span> is still joinable, <span style=\"font-family: courier new, courier;\">std::terminate<\/span> is called in its destructor. A thread <span style=\"font-family: 'courier new', courier;\">thr<\/span> is joinable if either <span style=\"font-family: courier new, courier;\">thr.join() <\/span>or <span style=\"font-family: courier new, courier;\">thr.detach()<\/span> was called.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ threadJoinable.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> thr{[]{ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Joinable std::thread\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }};\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"thr.joinable(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> thr.joinable() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>When executed, the program terminates.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5528\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/threadJoinable.png\" alt=\"threadJoinable\" width=\"500\" height=\"279\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/threadJoinable.png 644w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/threadJoinable-300x167.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Both threads terminate. In the second run, the thread thr has enough time to display its message: &#8220;Joinable std::thread&#8221;.<\/p>\n<p>In the following example, I replace the header<span style=\"font-family: courier new, courier;\"> &lt;thread&gt;<\/span> with <span style=\"font-family: courier new, courier;\">&#8220;jthread.hpp&#8221; <\/span>and use <span style=\"font-family: courier new, courier;\">std::jthread<\/span> from the upcoming C++ standard.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ jthreadJoinable.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include \"jthread.hpp\"<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>jthread thr{[]{ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Joinable std::thread\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }};\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"thr.joinable(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> thr.joinable() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the thread <span style=\"font-family: courier new, courier;\">thr<\/span> automatically joins in its destructor, such as in this case if still joinable.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5529\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthreadJoinable.png\" alt=\"jthreadJoinable\" width=\"350\" height=\"177\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthreadJoinable.png 443w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthreadJoinable-300x152.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/p>\n<h2>Interrupt a <span style=\"font-family: courier new, courier;\">std::jthread<\/span><\/h2>\n<p>To get a general idea, let me present a simple example.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ interruptJthread.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include \"jthread.hpp\"<\/span>\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span><span style=\"color: #555555;\">::<\/span>std<span style=\"color: #555555;\">::<\/span>literals;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>jthread nonInterruptable([]{                                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n        <span style=\"color: #007788; font-weight: bold;\">int<\/span> counter{<span style=\"color: #ff6600;\">0<\/span>};\r\n        <span style=\"color: #006699; font-weight: bold;\">while<\/span> (counter <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">10<\/span>){\r\n            std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(<span style=\"color: #ff6600;\">0.2<\/span>s);\r\n            std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"nonInterruptable: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> counter <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; \r\n            <span style=\"color: #555555;\">++<\/span>counter;\r\n        }\r\n    });\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>jthread interruptable([](std<span style=\"color: #555555;\">::<\/span>interrupt_token itoken){         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n        <span style=\"color: #007788; font-weight: bold;\">int<\/span> counter{<span style=\"color: #ff6600;\">0<\/span>};\r\n        <span style=\"color: #006699; font-weight: bold;\">while<\/span> (counter <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">10<\/span>){\r\n            std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(<span style=\"color: #ff6600;\">0.2<\/span>s);\r\n            <span style=\"color: #006699; font-weight: bold;\">if<\/span> (itoken.is_interrupted()) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n            std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"interruptable: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> counter <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; \r\n            <span style=\"color: #555555;\">++<\/span>counter;\r\n        }\r\n    });\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(<span style=\"color: #ff6600;\">1<\/span>s);\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Main thread interrupts both jthreads\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span> endl;\r\n    nonInterruptable.interrupt();\r\n    interruptable.interrupt();                                          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I started in the main program the two threads <span style=\"font-family: courier new, courier;\">nonInterruptable<\/span> and <span style=\"font-family: courier new, courier;\">interruptable<\/span> (lines 1 and 2). In contrast to the thread <span style=\"font-family: courier new, courier;\">nonInterruptable,<\/span> the thread <span style=\"font-family: courier new, courier;\">interruptable<\/span> gets a <span style=\"font-family: courier new, courier;\">std::interrupt_token<\/span> and uses it in line 3 to check if it was interrupted: <span style=\"font-family: courier new, courier;\">itoken.is_interrupted().<\/span> In case of an interrupt, the lambda function returns, and, therefore, the thread ends. The call<span style=\"font-family: courier new, courier;\"> interruptable.interrupt()<\/span> (line 4) triggers the end of the thread. This does not hold for the previous call <span style=\"font-family: courier new, courier;\">nonInterruptable.interrupt(),<\/span> which has no effect.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5530\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interruptJthread.png\" alt=\"interruptJthread\" width=\"400\" height=\"382\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interruptJthread.png 735w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interruptJthread-300x287.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Here are more details to interrupt tokens, the joining threads, and condition variables.<\/p>\n<h3>Interrupt Tokens<\/h3>\n<p>An interrupt token <span style=\"font-family: courier new, courier;\">std::interrupt_token<\/span> models shared ownership and can be used to signal once if the token is valid. It provides three methods <span style=\"font-family: courier new, courier;\">valid,<\/span> <span style=\"font-family: courier new, courier;\">is_interrupted,<\/span> and <span style=\"font-family: courier new, courier;\">interrupt.<\/span><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5531\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interrupt_token_fixed.png\" alt=\"interrupt token fixed\" width=\"600\" height=\"196\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interrupt_token_fixed.png 958w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interrupt_token_fixed-300x98.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/interrupt_token_fixed-768x251.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>If the interrupt token should be temporarily disabled, you can replace it with a default constructed token. A default constructed token is not valid. The following code snippet shows how to disable and enable a thread&#8217;s capability to accept signals.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">std<span style=\"color: #555555;\">::<\/span>jthread jthr([](std<span style=\"color: #555555;\">::<\/span>interrupt_token itoken){\r\n    ...\r\n    std<span style=\"color: #555555;\">::<\/span>interrupt_token interruptDisabled; \r\n    std<span style=\"color: #555555;\">::<\/span>swap(itoken, interruptDisabled);     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)       <\/span>\r\n    ...\r\n    std<span style=\"color: #555555;\">::<\/span>swap(itoken, interruptDisabled);     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    ...\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<span style=\"font-family: courier new, courier;\">std::interrupt_token interruptDisabled<\/span> is not valid. This means that the thread can not accept an interrupt from line (1) to (2), but after line (2), it&#8217;s possible.<\/p>\n<h3>Joining Threads<\/h3>\n<p>A <span style=\"font-family: courier new, courier;\">std::jhread<\/span> is a<span style=\"font-family: courier new, courier;\"> std::thread<\/span> with the additional functionality to automatically signal an interrupt and join (). To support this functionality, it has a <span style=\"font-family: courier new, courier;\">std::interrupt_token.<\/span><\/p>\n<h3><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5532\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthread.png\" alt=\"jthread\" width=\"600\" height=\"86\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthread.png 940w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthread-300x43.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/jthread-768x110.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/h3>\n<h3>New Wait Overloads for Condition Variables<\/h3>\n<p>The two wait variations <span style=\"font-family: courier new, courier;\"><\/span><span style=\"font-family: courier new, courier;\">wait_for<\/span>, and <span style=\"font-family: courier new, courier;\">wait_until<\/span> of the <span style=\"font-family: 'courier new', courier;\">std::condition_variable<\/span> get new overloads. They take a s<span style=\"font-family: courier new, courier;\">td::interrupt_token.<\/span><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Predicate<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> wait_until(unique_lock<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;&amp;<\/span> lock, \r\n                Predicate pred, \r\n                interrupt_token itoken);\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Rep<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Period<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Predicate<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> wait_for(unique_lock<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;&amp;<\/span> lock, \r\n              <span style=\"color: #006699; font-weight: bold;\">const<\/span> chrono<span style=\"color: #555555;\">::<\/span>duration<span style=\"color: #555555;\">&lt;<\/span>Rep, Period<span style=\"color: #555555;\">&gt;&amp;<\/span> rel_time, \r\n              Predicate pred, \r\n              interrupt_token itoken);\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Clock<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Duration<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Predicate<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> wait_until(unique_lock<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;&amp;<\/span> lock, \r\n                <span style=\"color: #006699; font-weight: bold;\">const<\/span> chrono<span style=\"color: #555555;\">::<\/span>time_point<span style=\"color: #555555;\">&lt;<\/span>Clock, Duration<span style=\"color: #555555;\">&gt;&amp;<\/span> abs_time, \r\n                Predicate pred, \r\n                interrupt_token itoken);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>These new overloads require a predicate. The versions ensure to get notified if an interrupt is signalled for the passed <span style=\"font-family: courier new, courier;\">std::interrupt_token itoken<\/span>. After the wait calls, you can check if an interrupt occurred.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">cv.wait_until(lock, predicate, itoken);\r\n<span style=\"color: #006699; font-weight: bold;\">if<\/span> (itoken.is_interrupted()){\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ interrupt occurred<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>As I promised in my last post, my <a href=\"http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-definition-of-concepts-the-second\">next post<\/a> is about the remaining rules for defining concepts.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the participants in my CppCon 2018 workshop asked me: &#8220;Can a std::thread be interrupted?&#8221;. No, that was my answer, but this is not correct anymore. With C++20, we might get a std::jthread.<\/p>\n","protected":false},"author":21,"featured_media":4724,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[367],"tags":[448],"class_list":["post-5533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading-c-17-and-c-20","tag-jthread"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5533"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5533\/revisions"}],"predecessor-version":[{"id":6809,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5533\/revisions\/6809"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4724"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}