{"id":7677,"date":"2023-06-26T10:52:04","date_gmt":"2023-06-26T10:52:04","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=7677"},"modified":"2023-08-27T11:57:10","modified_gmt":"2023-08-27T11:57:10","slug":"monitor-object","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/monitor-object\/","title":{"rendered":"Monitor Object"},"content":{"rendered":"\n<p><em>The<strong> monitor object design pattern<\/strong> synchronizes concurrent member function execution to ensure that only one member function at a time runs within an object. It also allows object\u2019s member functions to schedule their execution sequences cooperatively.<\/em> (<a href=\"https:\/\/www.dre.vanderbilt.edu\/~schmidt\/POSA\/POSA2\/\">Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects<\/a>)<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"520\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/ConcurrencyPatterns-1030x520.png\" alt=\"\" class=\"wp-image-7662\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/ConcurrencyPatterns-1030x520.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/ConcurrencyPatterns-300x151.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/ConcurrencyPatterns-768x387.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/ConcurrencyPatterns-705x356.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/ConcurrencyPatterns.png 1245w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<p>The Monitor Object design pattern synchronizes concurrent member function execution to ensure that only one member function runs within an object at a time. It also allows an object&#8217;s member functions to schedule their execution sequences cooperatively.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-1-also-know-as\">Also know as<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Thread-Safe Passive Object<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-2-problem\">Problem<\/h3>\n\n\n\n<p>If many threads access a shared object concurrently, the following challenges exist.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Due to the concurrent access, the shared object must be protected from non-synchronized read and write operations to avoid data races.<\/li>\n\n\n\n<li>The necessary synchronization should be part of the implementation, not the interface.<\/li>\n\n\n\n<li>When a thread is done with the shared object, a notification should be triggered so the next thread can use the shared object. This mechanism helps avoid and improves the system&#8217;s overall performance.<\/li>\n\n\n\n<li>After the execution of a member function, the invariants of the shared object must hold.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-3-solution\">Solution<\/h3>\n\n\n\n<p>A client (thread) can access the Monitor Object&#8217;s synchronized member functions, and due to the monitor lock, only one synchronized member function can run at any given time. Each Monitor Object has a monitor condition that notifies the waiting clients.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-4-components\">Components<\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"581\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-1030x581.jpg\" alt=\"\" class=\"wp-image-7678\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-1030x581.jpg 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-300x169.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-768x433.jpg 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-1536x866.jpg 1536w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-2048x1155.jpg 2048w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-1500x846.jpg 1500w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/MonitorObject-705x398.jpg 705w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Monitor Object<\/strong>: The Monitor Object supports one or more member functions. Each client must access the object through these member functions, and each member function runs in the client&#8217;s thread.<\/li>\n\n\n\n<li><strong>Synchronized member functions<\/strong>: The Monitor Object supports the synchronized member functions. Only one member function can execute at any given point in time. The <a href=\"https:\/\/www.modernescpp.com\/index.php\/dealing-with-mutation-thread-safe-interface\">Thread-Safe Interface <\/a>helps to distinguish between the interface member functions (synchronized member functions) and the implementation member functions of the Monitor Object.<\/li>\n\n\n\n<li><strong>Monitor lock<\/strong>: Each Monitor Object has one monitor lock, which ensures that at most one client can access the Monitor Object at any given time.<\/li>\n\n\n\n<li><strong>Monitor condition<\/strong>: The monitor condition allows separate threads to schedule their member function invocations on the Monitor Object. When the current client is done with its invocation of the synchronized member functions, the next waiting client is awakened to invoke the Monitor Object&#8217;s synchronized member functions.<\/li>\n<\/ul>\n\n\n\n<p>While the monitor lock ensures the synchronized member functions&#8217; exclusive access, the monitor condition guarantees minimal waiting for the clients. Essentially, the monitor lock protects from data races and the condition monitor from deadlocks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-5-dynamic-behavior\">Dynamic Behavior<\/h3>\n\n\n\n<p>The interaction between the Monitor Object and its components has different phases.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>When a client invokes a synchronized member function on a Monitor Object, it must first lock the global monitor lock. If the client successfully locks, it executes the synchronized member function and unlocks the monitor lock. If the client is not successful, the client is blocked. &nbsp;<\/li>\n\n\n\n<li>When the client is blocked because it cannot progress, it waits until the monitor condition sends a notification. This notification happens when the monitor is unlocked. The notification can be sent to one or all the waiting clients. Typically, waiting means resource-friendly sleeping in contrast to busy waiting.<\/li>\n\n\n\n<li>When a client gets the notification to resume, it locks the monitor lock and executes the synchronized member function. The monitor lock is unlocked at the end of the synchronized member function. The monitor sends a notification to signal that the next client can execute its synchronized member function.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-6-pros-and-cons\">Pros and Cons<\/h3>\n\n\n\n<p>What are the advantages and disadvantages of the Monitor Object?<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h0-6-1-pros\">Pros<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The client is not aware of the implicit synchronization of the Monitor Object, and the synchronization is fully encapsulated in the implementation.<\/li>\n\n\n\n<li>The invoked synchronized member functions will eventually be automatically scheduled. The notification\/waiting mechanism of the monitor condition behaves as a simple scheduler.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h0-6-2-cons\">Cons<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It is often quite challenging to change the synchronization mechanism of the synchronization member functions because the functionality and the synchronization are strongly coupled.<\/li>\n\n\n\n<li>When a synchronized member function invokes directly or indirectly the same Monitor Object, a deadlock may occur.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h0-7-example\">Example<\/h3>\n\n\n\n<p>The following example defines a <code>ThreadSafeQueue<\/code>.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ monitorObject.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;condition_variable&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;functional&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;queue&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;mutex&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;random&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;thread&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">Monitor<\/span> {\n<span style=\"color: #9999FF\">public:<\/span>\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> lock() <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n        monitMutex.lock();\n    }\n\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> unlock() <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n        monitMutex.unlock();\n    }\n\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> notify_one() <span style=\"color: #006699; font-weight: bold\">const<\/span> noexcept {\n        monitCond.notify_one();\n    }\n\n    <span style=\"color: #006699; font-weight: bold\">template<\/span> <span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> Predicate<span style=\"color: #555555\">&gt;<\/span>\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> wait(Predicate pred) <span style=\"color: #006699; font-weight: bold\">const<\/span> {                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (10)<\/span>\n        std<span style=\"color: #555555\">::<\/span>unique_lock<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>mutex<span style=\"color: #555555\">&gt;<\/span> monitLock(monitMutex);\n        monitCond.wait(monitLock, pred);\n    }\n    \n<span style=\"color: #9999FF\">private:<\/span>\n    <span style=\"color: #006699; font-weight: bold\">mutable<\/span> std<span style=\"color: #555555\">::<\/span>mutex monitMutex;\n    <span style=\"color: #006699; font-weight: bold\">mutable<\/span> std<span style=\"color: #555555\">::<\/span>condition_variable monitCond;\n};\n\n<span style=\"color: #006699; font-weight: bold\">template<\/span> <span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> T<span style=\"color: #555555\">&gt;<\/span>                                  <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">ThreadSafeQueue<\/span><span style=\"color: #555555\">:<\/span> <span style=\"color: #006699; font-weight: bold\">public<\/span> Monitor {\n <span style=\"color: #9999FF\">public:<\/span>\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> add(T val){ \n        lock();\n        myQueue.push(val);                             <span style=\"color: #0099FF; font-style: italic\">\/\/ (6)<\/span>\n        unlock();\n        notify_one();\n    }\n    \n    T get(){ \n        wait( [<span style=\"color: #006699; font-weight: bold\">this<\/span>] { <span style=\"color: #006699; font-weight: bold\">return<\/span> <span style=\"color: #555555\">!<\/span> myQueue.empty(); } );  <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n        lock();\n        <span style=\"color: #006699; font-weight: bold\">auto<\/span> val <span style=\"color: #555555\">=<\/span> myQueue.front();                    <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n        myQueue.pop();                                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (5)<\/span>\n        unlock();\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> val;\n    }\n\n<span style=\"color: #9999FF\">private:<\/span>\n    std<span style=\"color: #555555\">::<\/span>queue<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span> myQueue;                            <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n};\n\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">Dice<\/span> {\n<span style=\"color: #9999FF\">public:<\/span>\n    <span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #006699; font-weight: bold\">operator<\/span>()(){ <span style=\"color: #006699; font-weight: bold\">return<\/span> rand(); }\n<span style=\"color: #9999FF\">private:<\/span>\n    std<span style=\"color: #555555\">::<\/span>function<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>()<span style=\"color: #555555\">&gt;<\/span> rand <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>bind(std<span style=\"color: #555555\">::<\/span>uniform_int_distribution<span style=\"color: #555555\">&lt;&gt;<\/span>(<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">6<\/span>), \n                                          std<span style=\"color: #555555\">::<\/span>default_random_engine());\n};\n\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>(){\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    \n    constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> NumberThreads <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">100<\/span>;\n    \n    ThreadSafeQueue<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> safeQueue;                      <span style=\"color: #0099FF; font-style: italic\">\/\/ (7)<\/span>\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> addLambda <span style=\"color: #555555\">=<\/span> [<span style=\"color: #555555\">&amp;<\/span>safeQueue](<span style=\"color: #007788; font-weight: bold\">int<\/span> val){ safeQueue.add(val);          <span style=\"color: #0099FF; font-style: italic\">\/\/ (8)<\/span>\n                                            std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> val <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot; &quot;<\/span>\n                                            <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>this_thread<span style=\"color: #555555\">::<\/span>get_id() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;; &quot;<\/span>; \n                                          }; \n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> getLambda <span style=\"color: #555555\">=<\/span> [<span style=\"color: #555555\">&amp;<\/span>safeQueue]{ safeQueue.get(); };  <span style=\"color: #0099FF; font-style: italic\">\/\/ (9)<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span><span style=\"color: #555555\">&gt;<\/span> addThreads(NumberThreads);\n    Dice dice;\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;<\/span> thr<span style=\"color: #555555\">:<\/span> addThreads) thr <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span>(addLambda, dice());\n\n    std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span><span style=\"color: #555555\">&gt;<\/span> getThreads(NumberThreads);\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;<\/span> thr<span style=\"color: #555555\">:<\/span> getThreads) thr <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span>(getLambda);\n\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;<\/span> thr<span style=\"color: #555555\">:<\/span> addThreads) thr.join();\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;<\/span> thr<span style=\"color: #555555\">:<\/span> getThreads) thr.join();\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>;\n     \n}\n<\/pre><\/div>\n\n\n\n<p>The key idea of the example is that the Monitor Object is encapsulated in a class and can, therefore, be reused. The class&nbsp;<code>Monitor<\/code> uses a <code>std::mutex<\/code> as monitor lock and <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/condition-variable\"><code>std::condition_variable<\/code><\/a> as monitor condition. The class&nbsp;<code>Monitor<\/code> provides the minimal interface that a Monitor Object should support.<\/p>\n\n\n\n<p><code>ThreadSafeQueue<\/code> in line (1) extends&nbsp; <code>std::queue<\/code> in line (3) with a thread-safe interface. <code>ThreadSafeQueue<\/code> derives from the class <code>Monitor<\/code> and uses its member functions to support the synchronized member functions <code>add<\/code> and get. The member functions <code>add<\/code> and <code>get<\/code> use the monitor lock to protect the Monitor Object, particularly the non-thread-safe <code>myQueue<\/code>. <code>add<\/code> notifies the waiting thread when a new item was added to <code>myQueue<\/code>. This notification is thread-safe. The member function <code>get<\/code> (line (3)) deserves more attention. First, the <code>wait <\/code>member function of the underlying condition variable is called. This <code>wait<\/code> call needs an additional predicate to protect against spurious and lost wakeups (<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-be-aware-of-the-traps-of-condition-variables\">C++ Core Guidelines: Be Aware of the Traps of Condition Variables<\/a>). The operations modifying&nbsp; <code>myQueue<\/code> (lines 4 and 5) must also be protected because they can interleave with the call <code>myQueue.push(val)<\/code> (line 6). The Monitor Object <code>safeQueue<\/code> line (7) uses the lambda functions in lines (8) and (9) to add or remove a number from the synchronized <code>safeQueue<\/code>. <code>ThreadSafeQueue<\/code> itself is a class template and can hold values from an arbitrary type. One hundred clients add 100 random numbers between 1 &#8211; 6 to&nbsp; <code>safeQueue<\/code> (line 7), while hundred clients remove these 100 numbers concurrently from the <code>safeQueue<\/code>. The output of the program shows the numbers and the thread ids.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"931\" height=\"589\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/monitorObject.png\" alt=\"\" class=\"wp-image-7663\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/monitorObject.png 931w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/monitorObject-300x190.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/monitorObject-768x486.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/monitorObject-705x446.png 705w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><\/figure>\n\n\n\n<p>With C++20, the program <code>monitorObject.cp<\/code>p can be further improved. First, I include the header <code>&lt;concepts&gt;<\/code> and use the concept <code>std::predicate<\/code> as a restricted type parameter in the function template&nbsp;<code>wait<\/code> (line 10). The concept<code> std::predicate<\/code> ensures that the function template <code>wait<\/code> can only be instantiated with a predicate.&nbsp;Predicates are callables that return a boolean as a result.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #006699; font-weight: bold\">template<\/span> <span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>predicate Predicate<span style=\"color: #555555\">&gt;<\/span>\n<span style=\"color: #007788; font-weight: bold\">void<\/span> wait(Predicate pred) <span style=\"color: #006699; font-weight: bold\">const<\/span> {\n    std<span style=\"color: #555555\">::<\/span>unique_lock<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>mutex<span style=\"color: #555555\">&gt;<\/span> monitLock(monitMutex);\n    monitCond.wait(monitLock, pred);\n}\n<\/pre><\/div>\n\n\n\n<p>Second, I use <a href=\"https:\/\/www.modernescpp.com\/index.php\/an-improved-thread-with-c-20\"><code>std::jthread<\/code><\/a> instead of<code> std::thread<\/code>. <code>std::jthread<\/code> s an improved&nbsp;<code>std::thread<\/code> in C++20 that automatically joins in its destructor if necessary.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    \n    constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> NumberThreads <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">100<\/span>;\n    \n    ThreadSafeQueue<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> safeQueue;\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> addLambda <span style=\"color: #555555\">=<\/span> [<span style=\"color: #555555\">&amp;<\/span>safeQueue](<span style=\"color: #007788; font-weight: bold\">int<\/span> val){ safeQueue.add(val);\n                                            std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> val <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot; &quot;<\/span>\n                                            <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>this_thread<span style=\"color: #555555\">::<\/span>get_id() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;; &quot;<\/span>; \n                                          }; \n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> getLambda <span style=\"color: #555555\">=<\/span> [<span style=\"color: #555555\">&amp;<\/span>safeQueue]{ safeQueue.get(); };\n\n    std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>jthread<span style=\"color: #555555\">&gt;<\/span> addThreads(NumberThreads);\n    Dice dice;\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;<\/span> thr<span style=\"color: #555555\">:<\/span> addThreads) thr <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>jthread(addLambda, dice());\n\n    std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>jthread<span style=\"color: #555555\">&gt;<\/span> getThreads(NumberThreads);\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (<span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;<\/span> thr<span style=\"color: #555555\">:<\/span> getThreads) thr <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>jthread(getLambda);\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>;\n     \n}\n<\/pre><\/div>\n\n\n\n<p>The <a href=\"https:\/\/www.modernescpp.com\/index.php\/active-object\">Active Object<\/a> and the Monitor Object are similar but distinct in a few important points. Both architectural patterns synchronize access to a shared object. The member functions of an Active Object are executed in a different thread, but the Monitor Object member functions in the same thread. The Active Object decouples its member function invocation better from its member function execution and is, therefore, easier to maintain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h1-what-s-next\">What&#8217;s Next?<\/h2>\n\n\n\n<p><strong>DONE!<\/strong>&nbsp; I have written around 50 posts about <a href=\"https:\/\/www.modernescpp.com\/index.php\/category\/patterns\">patterns<\/a>. In my next posts, I will write about unknown features in C++17, dive deeper into C++20, and present the upcoming new C++23 standard. I will start this journey with C++23.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The monitor object design pattern synchronizes concurrent member function execution to ensure that only one member function at a time runs within an object. It also allows object\u2019s member functions to schedule their execution sequences cooperatively. (Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects) The Monitor Object design pattern synchronizes concurrent member function execution [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":7662,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[379],"tags":[],"class_list":["post-7677","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-patterns"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/7677","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=7677"}],"version-history":[{"count":4,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/7677\/revisions"}],"predecessor-version":[{"id":8040,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/7677\/revisions\/8040"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/7662"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=7677"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=7677"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=7677"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}