{"id":6092,"date":"2021-02-18T06:14:03","date_gmt":"2021-02-18T06:14:03","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/synchronized-outputstreams\/"},"modified":"2023-06-26T09:32:22","modified_gmt":"2023-06-26T09:32:22","slug":"synchronized-outputstreams","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/synchronized-outputstreams\/","title":{"rendered":"Synchronized Output Streams with C++20"},"content":{"rendered":"<p>What happens when you write without synchronization to<code> std::cout<\/code>? You get a mess. With C++20, this should not be anymore.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5199\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/TimelineCpp20.png\" alt=\"TimelineCpp20\" width=\"650\" height=\"253\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>Before I present synchronized output streams with C++20, I want to show non-synchronized output in C++11.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ coutUnsynchronized.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\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: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Worker<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  Worker(std<span style=\"color: #555555;\">::<\/span>string n)<span style=\"color: #555555;\">:<\/span>name(n) {};\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">operator<\/span>() (){\r\n      <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">3<\/span>; <span style=\"color: #555555;\">++<\/span>i) {\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ begin work<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>milliseconds(<span style=\"color: #ff6600;\">200<\/span>));      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ end work<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\": \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Work \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" done !!!\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n      }\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>string name;\r\n};\r\n\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> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Boss: Let's start working.<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n \r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> herb<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"Herb\"<\/span>));                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> andrei<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"  Andrei\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> scott<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"    Scott\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> bjarne<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"      Bjarne\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> bart<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"        Bart\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> jenne<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"          Jenne\"<\/span>));            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  \r\n  \r\n  herb.join();\r\n  andrei.join();\r\n  scott.join();\r\n  bjarne.join();\r\n  bart.join();\r\n  jenne.join();\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Boss: Let's go home.\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The boss has six workers (lines 1 &#8211; 2). Each worker has to take care of three work packages that take 1\/5 second each (line 3). After the worker is done with his work package, he screams out loudly to the boss (line 4). Once the boss receives notifications from all workers, he sends them home (line 5).<br \/>What a mess for such a simple workflow! Each worker screams out his message ignoring his coworkers!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6089\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/coutUnsynchronized.png\" alt=\"coutUnsynchronized\" width=\"500\" height=\"542\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/coutUnsynchronized.png 629w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/coutUnsynchronized-277x300.png 277w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<ul>\n<li><strong><code>std::cout<\/code> is thread-safe<\/strong>: The C++11 standard guarantees that you need&nbsp;not protect <code>std::cout<\/code>. Each character is written atomically. More output statements like those in the example may interleave. This interleaving is only a visual issue; the program is well-defined. This remark is valid for all global stream objects. Insertion to and extraction from global stream objects (<code>std::cout, std::cin, std::cerr<\/code>, and<code> std::clog<\/code>) is thread-safe. To put it more formally: writing to<code> std::cout<\/code> is not participating in a data race but does create a race condition. This means that the output depends on the interleaving of threads. Read more about the terms data race and race condition in my previous post:<a href=\"https:\/\/www.modernescpp.com\/index.php\/race-condition-versus-data-race\"> Race Conditions versus Data Races<\/a>.<\/li>\n<\/ul>\n<p>How can we solve this issue? With C++11, the answer is straightforward: use a lock such as <code>std::lock_guard<\/code> to synchronize the access to <code>std::cout<\/code>. For more information about locks in C++11, please read my previous post <a href=\"https:\/\/www.modernescpp.com\/index.php\/prefer-locks-to-mutexes\">Prefer Locks to Mutexes<\/a>.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ coutSynchronized.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;mutex&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;thread&gt;<\/span>\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>mutex coutMutex;                                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Worker<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  Worker(std<span style=\"color: #555555;\">::<\/span>string n)<span style=\"color: #555555;\">:<\/span>name(n) {};\r\n \r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">operator<\/span>() (){\r\n      <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">3<\/span>; <span style=\"color: #555555;\">++<\/span>i) { \r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ begin work<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>milliseconds(<span style=\"color: #ff6600;\">200<\/span>));\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ end work<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>lock_guard<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> coutLock(coutMutex);             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\": \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Work \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" done !!!\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n      }                                                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>string name;\r\n};\r\n\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> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Boss: Let's start working.\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n \r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> herb<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"Herb\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> andrei<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"  Andrei\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> scott<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"    Scott\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> bjarne<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"      Bjarne\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> bart<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"        Bart\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> jenne<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"          Jenne\"<\/span>));\r\n  \r\n  herb.join();\r\n  andrei.join();\r\n  scott.join();\r\n  bjarne.join();\r\n  bart.join();\r\n  jenne.join();\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Boss: Let's go home.\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <code>coutMutex<\/code> in line (1) protects the shared object<code> std::cout<\/code>. Putting the<code> coutMutex<\/code> into a <code>std::lock_guard<\/code> guarantees that the <code>coutMutex<\/code> is locked in the constructor (line 2) and unlocked in the destructor (line 3) of the <code>std::lock_guard.<\/code> Thanks to the <code>coutMutex<\/code> guarded by the<code> coutLock<\/code> the mess becomes harmony.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6090\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/coutSynchronized.png\" alt=\"coutSynchronized\" width=\"450\" height=\"615\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/coutSynchronized.png 514w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/coutSynchronized-220x300.png 220w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>With C++20, writing synchronized to <code>std::cout<\/code> is a piece of cake. <code>std::basic_syncbuf<\/code> is a wrapper for a <code>std::basic_streambuf<\/code>. It accumulates output in its buffer. The wrapper sets its content to the wrapped buffer when it is destructed. Consequently, the content appears as a contiguous sequence of characters, and no characters can interleave.<br \/>Thanks to <code>std::basic_osyncstream<\/code>, you can directly write synchronously to <code>std::cout<\/code> by using a named synchronized output stream<code>.<\/code><br \/>Here is how the previous program <code>coutUnsynchronized.cpp<\/code> is refactored to write synchronized to <code>std::cout<\/code>. So far, only GCC 11 supports synchronized output streams.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ synchronizedOutput.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;syncstream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Worker<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  Worker(std<span style=\"color: #555555;\">::<\/span>string n)<span style=\"color: #555555;\">:<\/span> name(n) {};\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">operator<\/span>() (){\r\n      <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">3<\/span>; <span style=\"color: #555555;\">++<\/span>i) {\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ begin work<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>milliseconds(<span style=\"color: #ff6600;\">200<\/span>));\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ end work<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>osyncstream syncStream(std<span style=\"color: #555555;\">::<\/span>cout);                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n        syncStream <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\": \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Work \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span><br \/>                   <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" done !!!\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n      }                                                            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>string name;\r\n};\r\n\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> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Boss: Let's start working.<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n \r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> herb<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"Herb\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> andrei<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"  Andrei\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> scott<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"    Scott\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> bjarne<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"      Bjarne\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> bart<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"        Bart\"<\/span>));\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span> jenne<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">thread<\/span>(Worker(<span style=\"color: #cc3300;\">\"          Jenne\"<\/span>));\r\n  \r\n  \r\n  herb.join();\r\n  andrei.join();\r\n  scott.join();\r\n  bjarne.join();\r\n  bart.join();\r\n  jenne.join();\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Boss: Let's go home.\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The only change to the previous program <code>coutUnsynchronized.cpp<\/code> is that <code>std::cout<\/code> is wrapped in a <code>std::osyncstream<\/code> (line 1). When the <code>std::osyncstream<\/code> goes out of scope in line (2), the characters are transferred and <code>std::cout<\/code> is flushed. It is worth mentioning that the<code> std::cout<\/code> calls in the main program do not introduce a data race and, therefore, need not be synchronized. The output happens before or after the output of the threads.<\/p>\n<p>Because I use the <code>syncStream<\/code> declared on line (3) only once, a temporary object may be more appropriate. The following code snippet presents the modified call operator:<\/p>\n<p><!-- HTML generated using hilite.me --><\/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: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">operator<\/span>()() {\r\n  <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">3<\/span>; <span style=\"color: #555555;\">++<\/span>i) { \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ begin work<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>this_thread<span style=\"color: #555555;\">::<\/span>sleep_for(std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>milliseconds(<span style=\"color: #ff6600;\">200<\/span>));\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ end work<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>osyncstream(std<span style=\"color: #555555;\">::<\/span>cout) <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\": \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Work \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" done !!!\"<\/span> \r\n                                <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><code>std::basic_osyncstream syncStream<\/code> offers two interesting member functions.<\/p>\n<ul>\n<ul>\n<li><code>syncStream.emit()<\/code> emits all buffered output and executes all pending flushes.<\/li>\n<li><code>syncStream.get_wrapped()<\/code> returns a pointer to the wrapped buffer.<\/li>\n<\/ul>\n<\/ul>\n<p><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/io\/basic_osyncstream\/get_wrapped\">cppreference.com<\/a> shows how you can sequence the output of different output streams with the <code>get_wrapped<\/code> member function.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ sequenceOutput.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;syncstream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\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>osyncstream bout1(std<span style=\"color: #555555;\">::<\/span>cout);\r\n  bout1 <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Hello, \"<\/span>;\r\n  {\r\n      std<span style=\"color: #555555;\">::<\/span>osyncstream(bout1.get_wrapped()) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Goodbye, \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Planet!\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  } <span style=\"color: #0099ff; font-style: italic;\">\/\/ emits the contents of the temporary buffer<\/span>\r\n  \r\n  bout1 <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"World!\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n} <span style=\"color: #0099ff; font-style: italic;\">\/\/ emits the contents of bout1<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6091\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/02\/sequenceOutput.png\" alt=\"sequenceOutput\" style=\"display: block; margin-left: auto; margin-right: auto;\" width=\"196\" height=\"63\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Wow! Now I&#8217;m done with C++20. I have written about 70 posts on <a href=\"https:\/\/www.modernescpp.com\/index.php\/category\/c-20\">C++20<\/a>. You can have more information on C++20 in my book: <a href=\"https:\/\/leanpub.com\/c20\">C++20: Get the Details<\/a>.<\/p>\n<p>But there is still one feature I want to give more insight into coroutines. In my <a href=\"https:\/\/www.modernescpp.com\/index.php\/implementing-futures-with-coroutines\">next posts,<\/a> I will start to play with the new keywords <code>co_return<\/code>, <code>co_yield<\/code>, and <code>co_await. <\/code><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<div id=\"simple-translate\">&nbsp;<\/div>\n","protected":false},"excerpt":{"rendered":"<p>What happens when you write without synchronization to std::cout? You get a mess. With C++20, this should not be anymore.<\/p>\n","protected":false},"author":21,"featured_media":5199,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[447],"class_list":["post-6092","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-in-output"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6092","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=6092"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6092\/revisions"}],"predecessor-version":[{"id":6713,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6092\/revisions\/6713"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5199"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}