{"id":6571,"date":"2023-06-18T20:30:27","date_gmt":"2023-06-18T20:30:27","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/active-object\/"},"modified":"2023-06-25T09:06:27","modified_gmt":"2023-06-25T09:06:27","slug":"active-object","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/active-object\/","title":{"rendered":"Active Object"},"content":{"rendered":"<p><em>The <b>active object<\/b> design pattern decouples method execution from method invocation for objects that each reside in their own thread of control.The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests<\/em>. (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Active_object\">Wikipedia:Active Objec<\/a>t)<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6551\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/04\/ConcurrencyPatterns.png\" alt=\"ConcurrencyPatterns\" width=\"650\" height=\"328\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>The Active Object decouples method invocation from method execution. The method invocation is performed on the client thread, but the method execution is on the Active Object. The Active Object has its thread and a list of method request objects (short request) to be executed. The client\u2019s method invocation enqueues the requests on the Active Object\u2019s list. The requests are dispatched to the servant.<\/p>\n<h3>Also known as<\/h3>\n<ul>\n<li>Concurrent object<\/li>\n<\/ul>\n<h3>Problem<\/h3>\n<p>When many threads access a shared object synchronized, the following challenges must be solved:<\/p>\n<ul>\n<li>A thread invoking a processing-intensive member function should not block the other threads invoking the same object for too long.<\/li>\n<li>It should be easy to synchronize access to a shared object.<\/li>\n<li>The concurrency characteristics of the executed requests should be adaptable to the concrete hardware and software.<\/li>\n<\/ul>\n<h3>Solution<\/h3>\n<ul>\n<li>The client\u2019s method invocation goes to a proxy, which represents the interface of the Active Object.<\/li>\n<li>The servant implements these member functions and runs in the Active Object\u2019s thread. At run time, the proxy transforms the invocation into a method invocation on the servant. This request is enqueued in an activation list by the scheduler.<\/li>\n<li>A scheduler\u2019s event loop runs in the same thread as the servant, deques the requests from the activation list, removes them and dispatches them to the servant.<\/li>\n<li>The client obtains the method invocation result via a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Futures_and_promises\">future <\/a>from the <a href=\"https:\/\/www.modernescpp.com\/index.php\/the-proxy-pattern\">proxy<\/a>.<\/li>\n<\/ul>\n<h3>Components<\/h3>\n<div>\n<div>The Active Object pattern consists of six components:<\/div>\n<p><\/p>\n<ol>\n<li>The <strong>proxy<\/strong> provides an interface for the accessible member functions on the Active Object. The proxy triggers the construction of a request into the activation list. The proxy runs in the client thread.<\/li>\n<li>The<strong> method request<\/strong> class defines the interface for the method executing on an Active Object. This interface also contains guard methods, indicating if the job is ready to run. The request includes all context information to be executed later.<\/li>\n<li>The&nbsp;<strong>activation list<\/strong> maintains the pending requests. The activation list decouples the client&#8217;s thread from the Active Object thread. The proxy inserts the request object, and the scheduler removes them. Consequently, the access to the activation list must be serialized.<\/li>\n<li>The&nbsp;<strong>scheduler<\/strong> runs in the thread of the Active Object and decides which request from the activation list is executed next. The scheduler evaluates the guards of the request to determine if the request can run.<\/li>\n<li>The&nbsp;<strong>servan<\/strong>t implements the Active Object and runs in the active object&#8217;s thread. The servant implements the interface of the method request, and the scheduler invokes its member functions.<\/li>\n<li>The proxy creates the<strong> future <\/strong>and s only necessary if the request returns a result. Therefore, the client receives the future and can obtain the method invocation result on the Active Object. The client can wait for the outcome or poll for it.<\/li>\n<\/ol>\n<h3>Dynamic Behavior<\/h3>\n<\/div>\n<div>\n<div>The dynamic behavior of the Active Object consists of three phases:<\/div>\n<p><\/p>\n<ol>\n<li><strong>Request construction and scheduling<\/strong>: The client invokes a method on the proxy. The proxy creates a request and passes it to the scheduler. The scheduler enqueues the request on the activation list. Additionally, the proxy returns a future to the client if the request returns a result.<\/li>\n<li><strong>Member function execution<\/strong>: The scheduler determines which request becomes runnable by evaluating the guard method of the request. It removes the request from the activation list and dispatches it to the servant.&nbsp;<\/li>\n<li><strong>Completion<\/strong>: When the request returns something, it is stored in the future. The client can ask for the result. When the client has the result, the request and the future can be deleted.<\/li>\n<\/ol>\n<div>The following picture shows the sequence of messages.<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6569\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-scaled.jpg\" alt=\"ActiveObject\" width=\"650\" height=\"701\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-scaled.jpg 2373w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-278x300.jpg 278w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-949x1024.jpg 949w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-768x829.jpg 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-1424x1536.jpg 1424w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/ActiveObject-1898x2048.jpg 1898w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Pros and Cons<\/h3>\n<div>\n<div>Before I present a minimal example of the Active Object, here are its pros and cons.<\/div>\n<h4>Pros<\/h4>\n<\/div>\n<ul>\n<li>Synchronization is only required on the Active Object&#8217;s thread but not on the client&#8217;s threads.<\/li>\n<li>Clear separation between the client (user) and the server (implementer). The synchronization challenges are on the implementer&#8217;s side.&nbsp;<\/li>\n<li>Enhanced throughput of the system because of the asynchronous execution of the requests. Invoking processing-intensive member functions do not block the entire system.<\/li>\n<li>The scheduler can implement various strategies to execute the pending requests. If so, the jobs can be executed in a different order they are enqueued.<\/li>\n<\/ul>\n<h4>Cons<\/h4>\n<ul>\n<li>If the requests are too fine-grained, the Active Object pattern&#8217;s performance overhead, such as the proxy, the activation list, and the scheduler, may be excessive.<\/li>\n<li>Due to the scheduler&#8217;s scheduling strategy and the operating system&#8217;s scheduling, debugging the Active Object is often tricky. In particular, if the jobs are executed in a different order, they are enqueued.<\/li>\n<\/ul>\n<h3>Example<\/h3>\n<div><\/p>\n<div>The following example presents a simplified implementation of the Active Object. In particular, I don&#8217;t define an interface for the method requests on the Active Object, which the proxy and the servant should implement. Further, the scheduler executes the next job when asked for it, and the <code>run<\/code> member function of the Active Object creates the threads.<\/div>\n<p><\/p>\n<div>The involved types<code> future&lt;vector&lt;future&lt;pair&lt;bool, int&gt;&gt;&gt;&gt;<\/code> are often quite verbose. To improve the readability, I heavily applied using declarations (line 1). This example requires a solid knowledge of promises and futures in C++. My posts about <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/tasks\">tasks <\/a>provide more details.<\/div>\n<div>&nbsp;<\/div>\n<\/div>\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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ activeObject.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;deque&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;functional&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;future&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;memory&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;mutex&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;numeric&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;random&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;thread&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>async;                                              <span style=\"color: #0099ff;\"> <em>\/\/ (1)<\/em><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>cout;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>deque;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>distance;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>for_each;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>find_if;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>future;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>lock_guard;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>make_move_iterator;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>make_pair;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>move;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>mt19937;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>mutex;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>packaged_task;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>pair;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>random_device;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>sort;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>jthread;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>uniform_int_distribution;\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>vector;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">IsPrime<\/span> {                                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (8)<\/span>\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    IsPrime(<span style=\"color: #007788; font-weight: bold;\">int<\/span> num)<span style=\"color: #555555;\">:<\/span> numb{num} {} \r\n    pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span>()() {\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> j <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>; j <span style=\"color: #555555;\">*<\/span> j <span style=\"color: #555555;\">&lt;=<\/span> numb; <span style=\"color: #555555;\">++<\/span>j){\r\n            <span style=\"color: #006699; font-weight: bold;\">if<\/span> (numb <span style=\"color: #555555;\">%<\/span> j <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span> make_pair(<span style=\"color: #336666;\">false<\/span>, numb);\r\n        }\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> make_pair(<span style=\"color: #336666;\">true<\/span>, numb);\r\n    }\r\n <span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> numb;       \r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">ActiveObject<\/span> {\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    \r\n    future<span style=\"color: #555555;\">&lt;<\/span>pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&gt;<\/span> enqueueTask(<span style=\"color: #007788; font-weight: bold;\">int<\/span> i) {\r\n        IsPrime isPrime(i);\r\n        packaged_task<span style=\"color: #555555;\">&lt;<\/span>pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>()<span style=\"color: #555555;\">&gt;<\/span> newJob(isPrime);\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> isPrimeFuture <span style=\"color: #555555;\">=<\/span> newJob.get_future();\r\n        {\r\n            lock_guard<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> lockGuard(activationListMutex);\r\n            activationList.push_back(move(newJob));            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/span>\r\n        }\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> isPrimeFuture;\r\n    }\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> run() {\r\n        std<span style=\"color: #555555;\">::<\/span>jthread j([<span style=\"color: #006699; font-weight: bold;\">this<\/span>] {                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (12)<\/span>\r\n            <span style=\"color: #006699; font-weight: bold;\">while<\/span> ( <span style=\"color: #555555;\">!<\/span>runNextTask() );                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (13)<\/span>\r\n        });\r\n    }\r\n\r\n <span style=\"color: #9999ff;\">private:<\/span>\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> runNextTask() {                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (14)<\/span>\r\n        lock_guard<span style=\"color: #555555;\">&lt;<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> lockGuard(activationListMutex);\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> empty <span style=\"color: #555555;\">=<\/span> activationList.empty();\r\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> (<span style=\"color: #555555;\">!<\/span>empty) {                                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (15)<\/span>\r\n            <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myTask<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>move(activationList.front());\r\n            activationList.pop_front();\r\n            myTask();\r\n        }\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> empty;\r\n    }\r\n\r\n    deque<span style=\"color: #555555;\">&lt;<\/span>packaged_task<span style=\"color: #555555;\">&lt;<\/span>pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>()<span style=\"color: #555555;\">&gt;&gt;<\/span> activationList;      <span style=\"color: #0099ff; font-style: italic;\">\/\/(7)<\/span>\r\n    mutex activationListMutex;\r\n};\r\n\r\nvector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> getRandNumbers(<span style=\"color: #007788; font-weight: bold;\">int<\/span> number) {\r\n    random_device seed;\r\n    mt19937 <span style=\"color: #cc00ff;\">engine<\/span>(seed());\r\n    uniform_int_distribution<span style=\"color: #555555;\">&lt;&gt;<\/span> dist(<span style=\"color: #ff6600;\">1<\/span><span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span><span style=\"color: #ff6600;\">000<\/span><span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span><span style=\"color: #ff6600;\">000<\/span>, <span style=\"color: #ff6600;\">1<\/span><span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span><span style=\"color: #ff6600;\">000<\/span><span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span><span style=\"color: #ff6600;\">000<\/span><span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span><span style=\"color: #ff6600;\">000<\/span>);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> numbers;\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span> ; i <span style=\"color: #555555;\">&lt;<\/span> number; <span style=\"color: #555555;\">++<\/span>i) numbers.push_back(dist(engine)); \r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> numbers;\r\n}\r\n\r\nfuture<span style=\"color: #555555;\">&lt;<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>future<span style=\"color: #555555;\">&lt;<\/span>pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&gt;&gt;&gt;<\/span> getFutures(ActiveObject<span style=\"color: #555555;\">&amp;<\/span> activeObject, \r\n                                                   <span style=\"color: #007788; font-weight: bold;\">int<\/span> numberPrimes) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> async([<span style=\"color: #555555;\">&amp;<\/span>activeObject, numberPrimes] {\r\n        vector<span style=\"color: #555555;\">&lt;<\/span>future<span style=\"color: #555555;\">&lt;<\/span>pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&gt;&gt;<\/span> futures;\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> randNumbers <span style=\"color: #555555;\">=<\/span> getRandNumbers(numberPrimes);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> numb<span style=\"color: #555555;\">:<\/span> randNumbers){\r\n            futures.push_back(activeObject.enqueueTask(numb));  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n        }\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> futures;\r\n    });\r\n}\r\n    \r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main() {\r\n    \r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> boolalpha <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\n     ActiveObject activeObject;\r\n        \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ a few clients enqueue work concurrently                  \/\/ (2)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> client1 <span style=\"color: #555555;\">=<\/span> getFutures(activeObject, <span style=\"color: #ff6600;\">1998<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> client2 <span style=\"color: #555555;\">=<\/span> getFutures(activeObject, <span style=\"color: #ff6600;\">2003<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> client3 <span style=\"color: #555555;\">=<\/span> getFutures(activeObject, <span style=\"color: #ff6600;\">2011<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> client4 <span style=\"color: #555555;\">=<\/span> getFutures(activeObject, <span style=\"color: #ff6600;\">2014<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> client5 <span style=\"color: #555555;\">=<\/span> getFutures(activeObject, <span style=\"color: #ff6600;\">2017<\/span>);\r\n    \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ give me the futures                                      \/\/ (9)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> futures <span style=\"color: #555555;\">=<\/span> client1.get();\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> futures2 <span style=\"color: #555555;\">=<\/span> client2.get();\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> futures3 <span style=\"color: #555555;\">=<\/span> client3.get();\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> futures4 <span style=\"color: #555555;\">=<\/span> client4.get();\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> futures5 <span style=\"color: #555555;\">=<\/span> client5.get();\r\n    \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ put all futures together                                 \/\/ (10)<\/span>\r\n    futures.insert(futures.end(),make_move_iterator(futures2.begin()), \r\n                                 make_move_iterator(futures2.end()));\r\n    \r\n    futures.insert(futures.end(),make_move_iterator(futures3.begin()), \r\n                                 make_move_iterator(futures3.end()));\r\n    \r\n    futures.insert(futures.end(),make_move_iterator(futures4.begin()), \r\n                                 make_move_iterator(futures4.end()));\r\n    \r\n    futures.insert(futures.end(),make_move_iterator(futures5.begin()), \r\n                                 make_move_iterator(futures5.end()));\r\n        \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ run the promises                                         \/\/ (11)<\/span>\r\n    activeObject.run();\r\n    \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ get the results from the futures<\/span>\r\n    vector<span style=\"color: #555555;\">&lt;<\/span>pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&gt;<\/span> futResults;\r\n    futResults.reserve(futures.size());\r\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> fut<span style=\"color: #555555;\">:<\/span> futures) futResults.push_back(fut.get());   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (16)<\/span>\r\n    \r\n    sort(futResults.begin(), futResults.end());                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (17)<\/span>\r\n    \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ separate the primes from the non-primes<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> prIt <span style=\"color: #555555;\">=<\/span> find_if(futResults.begin(), futResults.end(), \r\n                        [](pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> pa){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> pa.first <span style=\"color: #555555;\">==<\/span> <span style=\"color: #336666;\">true<\/span>; });\r\n \r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Number primes: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> distance(prIt, futResults.end()) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;       <span style=\"color: #0099ff; font-style: italic;\">\/\/ (19)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Primes:\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    for_each(prIt, futResults.end(), [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> p){ cout <span style=\"color: #555555;\">&lt;&lt;<\/span> p.second <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;} );    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (20)<\/span>\r\n    \r\n    cout <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    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Number no primes: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> distance(futResults.begin(), prIt) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (18)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"No primes:\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    for_each(futResults.begin(), prIt, [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> p){ cout <span style=\"color: #555555;\">&lt;&lt;<\/span> p.second <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;} );\r\n    \r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<div>\n<div>&nbsp;<\/div>\n<div>First, the example&#8217;s general idea is that clients can enqueue jobs concurrently on the activation list. The servant determines which numbers are prime, and the activation list is part of the Active Object. The Active Object runs the jobs enqueued in the activation list on a separate thread, and the clients can ask for the results. &nbsp;<\/div>\n<p><\/p>\n<div>Here are the details.<\/div>\n<div>The five clients enqueue the work (line 2) on the <code>activeObject<\/code> via the <code>getFutures<\/code> function. <code>getFutures<\/code> takes the <code>activeObject<\/code> and a number <code>numberPrimes<\/code>. <code>numberPrimes<\/code> random numbers are generated (line 3) between 1&#8217;000&#8217;000 and 1&#8217;000&#8217;000&#8217;000 (line 4) and pushed on the return value: <code>vector&lt;future&lt;pair&lt;bool, int&gt;&gt;<\/code>. <code>future&lt;pair&lt;bool, int&gt;<\/code> holds a <code>bool<\/code> and an <code>int<\/code>. The bool indicates if the <code>int<\/code> is a prime. Let&#8217;s have a closer look at line (5): <code>futures.push_back(activeObject.enqueueTask(numb))<\/code>. This call triggers that a new job is enqueued on the activation list (line 6). All calls on the activation list have to be protected. The activation list is a deque of promises (line 7): <code>deque&lt;packaged_task&lt;pair&lt;bool, int&gt;()&gt;&gt;<\/code>. Each promise performs the function object <code>IsPrime<\/code> (line 8) when called. The return value is a pair of a <code>bool<\/code> and an <code>int<\/code>. The&nbsp;bool indicates if the number <code>int<\/code> is prime.<\/div>\n<p><\/p>\n<div>Now, the work packages are prepared. Let&#8217;s start the calculation. All clients return in line (9)&nbsp; their handles to the associated futures. Putting all futures together (line 10) makes my job easier. The call <code>activeObject.run()<\/code> in line (11) starts the execution. The member function <code>run<\/code> (line 12) creates the thread to execute the member function <code>runNextTask<\/code> (line 13). <code>runNextTask<\/code> (line 14) determines if the deque is not empty (line 15) and creates the new task. By calling <code>futResults.push_back(fut.get())<\/code> (line 16) on each future, all results are requested and pushed on <code>futResults<\/code>. Line (17) sorts the vector of pairs: <code>vector&lt;pair&lt;bool, int&gt;&gt;<\/code>. The remaining lines present the calculation. The iterator&nbsp;<code>prIt<\/code> in line 18 holds the first iterator to a pair that has a prime number. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<\/div>\n<div>The screenshot shows the number of primes <code>distance(prIt, futResults.end())<\/code> (line 19) and the primes (line 20). Only the first non-primes are displayed.<\/div>\n<div>&nbsp;<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6570\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/activeObject.png\" alt=\"activeObject\" width=\"650\" height=\"508\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/activeObject.png 1201w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/activeObject-300x235.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/activeObject-1024x801.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/06\/activeObject-768x600.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/div>\n<h2>What&#8217;s Next?<\/h2>\n<p>The Active Object and Monitor Object synchronize and schedule member function invocation. The main difference is that the Active Object executes its member function in a different thread, but the Monitor Object is in the same thread as the client. In my next post, I will present the Monitor Object.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<div>&nbsp;<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The active object design pattern decouples method execution from method invocation for objects that each reside in their own thread of control.The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests. (Wikipedia:Active Object)<\/p>\n","protected":false},"author":21,"featured_media":6551,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[379],"tags":[],"class_list":["post-6571","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\/6571","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=6571"}],"version-history":[{"count":2,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6571\/revisions"}],"predecessor-version":[{"id":7549,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6571\/revisions\/7549"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6551"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6571"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6571"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6571"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}