Design of the object pool

Source: Internet
Author: User

Design and implementation of object pool

Object Pooling Overview:

The object pool model creates and has a fixed number of objects that, when a new object is needed by the program, returns immediately if there are idle objects in the object pool, otherwise the new class object is created. When an object is no longer in use, it should be put back into the object pool for later use by the program. Due to limited system resources, an object pool model should specify the maximum number of objects it can accommodate. When this number is reached, if there is still an object creation request, an exception is thrown or the current calling thread is blocked until an object is put back into the object pool.

Scenarios where the object pool model applies:

(1) need to use a large number of objects

(2) The instantiation overhead of these objects is relatively large and the lifetime is relatively short

Object Pool Benefits:

An object pool can be created successfully and put into use within a tolerable time. But this is not always the case when creating objects, especially when the creation of these objects is time-consuming and the creation and destruction frequencies are relatively large. such as database connections, network socket connections, thread objects, image objects such as fonts or bitmaps, and so on.

Realize:

The following class definitions are assumed:

1 class object 2 {3 Public:4     object (const string& name): name_ (name) 5     {6         printf ("Construct object[%p] %s.\n ", this, Name_.c_str ()); 7     } 8  9     ~object ()     {one         printf ("~destruct object[%p]%s.\n", this, Name_.c_str ());     }13 14     Const string& Key () const {return name_;} Private:17     string name_;18};

The following object pool classes are designed to provide object class objects in 2 versions: (Note that the following only considers the attributes involved in the object pool itself and does not involve a synchronization control mechanism)

version 1 :

1 class Objectpool 2 {3 public:4     boost::shared_ptr<object> get (const string& key) 5     {6         Boost::sha Red_ptr<object> Pobject; 7         boost::weak_ptr<object>& k_object = Objects_[key]; 8         pobject = K_object.lock (); 9         if (!pobject )         {             pobject.reset (new Object (key),                          Boost::bind (&objectpool::releaseobject, this, _1)); 13             k_object = pobject;14         }         return pobject;16   }17 private:19     void Releaseobject (object* Object)         Releaseobject[%p].\n ", object),         if (object)             objects_.erase (Object->key ()), and         }26         Delete object;27     }     std::map<string, boost::weak_ptr<object> > objects_;30};

The Get function of the Objectpool returns the object that corresponds to the key in the map. If the object does not exist, create a new object, put it in the map, and return to the new object. Also, when resetting shared_ptr (new Object object), specify the destructor Releaseobject, which causes the object to execute Releaseobject (object) when it is refactored;

However, there is a problem with this implementation: When you pass this to the BIND function, if the Objectpool object is first refactored on the object, how do you call the Releaseobject function when you destructor the object? (Because the Releaseobject function belongs to the Objectpool class)

Version 2 :

1 class Objectpool:public boost::enable_shared_from_this<objectpool> 2 {3 Public:4     boost::shared_ptr< Object> get (const string& key) 5     {6         boost::shared_ptr<object> pobject; 7         boost::weak_ptr <Object>& k_object = Objects_[key]; 8         pobject = K_object.lock (); 9         if (!pobject)         {             pobject.reset (new object),                          shared_ From_this (), _1));             k_object = pobject;14         }15         return pobject;16     }17 void Releaseobject (Object* object)     {         23 printf ("releaseobject[%p].\n", object);         {             objects_.erase (Object->key ());         }26         Delete object;27     }28     std::map< String, boost::weak_ptr<object> > objects_;30};

To solve the problem in version 1, simply increase the lifespan of the objectpool. You can take advantage of shared_from_this () in the Boost::enable_shared_from_this template class so that this can be converted to shared_ptr<objectpool>. Thus, because bind is a value-passing semantics, it is necessary to keep a copy of shared_ptr<objectpool>, which guarantees that the reference count of shared_ptr is not 0.

test Case:

object_pool.cc
#include <map>

#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

#include <stdio.h>

Using Std::string;
const int maxnum = 5; The largest amounts of objects
int nums = 0; The current amounts of objects

Class Object
{
Public
Object (const string& name): name_ (name)
{
printf ("Construct object[%p]%s.\n", this, Name_.c_str ());
}

~object ()
{
printf ("~destruct object[%p]%s.\n", this, Name_.c_str ());
}

Const string& Key () const {return name_;}

Private
String name_;
};


Namespace Version1
{

Class Objectpool
{
Public
Boost::shared_ptr<object> get (const string& key)
{
Boost::shared_ptr<object> Pobject;
boost::weak_ptr<object>& k_object = Objects_[key];
Pobject = K_object.lock ();
if (!pobject)
{
++nums;
Boost_assert (nums <= maxnum);
Pobject.reset (The new Object (key),
Boost::bind (&objectpool::releaseobject, this, _1));
K_object = Pobject;
}
return pobject;
}

Private
void Releaseobject (object* Object)
{
printf ("releaseobject[%p].\n", object);
if (object)
{
--nums;
Objects_.erase (Object->key ());
}
Delete object;
}

Std::map<string, boost::weak_ptr<object> > Objects_;
};

}

Namespace Version2
{

Class Objectpool:public Boost::enable_shared_from_this<objectpool>
{
Public
Boost::shared_ptr<object> get (const string& key)
{
Boost::shared_ptr<object> Pobject;
boost::weak_ptr<object>& k_object = Objects_[key];
Pobject = K_object.lock ();
if (!pobject)
{
++nums;
Boost_assert (nums <= maxnum);
Pobject.reset (The new Object (key),
Boost::bind (&objectpool::releaseobject, Shared_from_this (), _1));
K_object = Pobject;
}
return pobject;
}

Private
void Releaseobject (object* Object)
{
printf ("releaseobject[%p].\n", object);
if (object)
{
--nums;
Objects_.erase (Object->key ());
}
Delete object;
}

Std::map<string, boost::weak_ptr<object> > Objects_;
};

}


int main ()
{
boost::shared_ptr<version1::objectpool> OP1 (new Version1::objectpool);

boost::shared_ptr<object> Object1 = Op1->get ("Object1");
Boost::shared_ptr<object> object2 = Op1->get ("Object2");
boost::shared_ptr<object> object3 = Op1->get ("Object3");
boost::shared_ptr<object> Object4 = Op1->get ("Object4");
boost::shared_ptr<object> object5 = Op1->get ("Object5");
boost::shared_ptr<object> OBJECT6 = Op1->get ("Object5");

Boost::shared_ptr<version2::objectpool> OP2 (new Version2::objectpool);
boost::shared_ptr<object> object7 = Op2->get ("Object2");
boost::shared_ptr<object> object8 = Op2->get ("Object2");

return 0;
}

Output
Construct object[003e1060] Object1.
Construct Object[003e10e0] Object2.
Construct object[003e1160] Object3.
Construct Object[003e11e0] Object4.
Construct object[003e1260] Object5.
RELEASEOBJECT[003E1260].
~destruct object[003e1260] Object5.
RELEASEOBJECT[003E11E0].
~destruct Object[003e11e0] Object4.
RELEASEOBJECT[003E1160].
~destruct object[003e1160] Object3.
RELEASEOBJECT[003E10E0].
~destruct Object[003e10e0] Object2.
RELEASEOBJECT[003E1060].
~destruct object[003e1060] Object1.

  1//object_pool.cc 2 #include <map> 3 4 #include <boost/bind.hpp> 5 #include <boost/enable_shared_f Rom_this.hpp> 6 #include <boost/shared_ptr.hpp> 7 #include <boost/weak_ptr.hpp> 8 9 #include <stdio .h> using Std::string;  a const int maxnum = 5;          The largest amounts of objects int nums = 0; The current amounts of objects-class object, {public:18 object (const string& name): name_ (name)         * printf ("Construct object[%p]%s.\n", this, Name_.c_str ()) (+ 24) ~object () {25} printf ("~destruct object[%p]%s.\n", this, Name_.c_str ()); string& key () const {return name_;} private:31 string name_; 32}; Namespace Version1 (boost::shared_ptr<object>) (Objectpool) (public:41 cons get T string& key) (Boost::shared_ptr<object> pobject;st::weak_ptr<object>& k_object = Objects_[key]; Pobject = K_object.lock ();             if (!pobject) ++nums, Boost_assert (nums <= maxnum); 50 Pobject.reset (New Object (key), Boost::bind (&objectpool::releaseobject, this, _1)); K_object = Pobject; +-----return pobject; private:58 void Releaseobject (Object* object) ("releaseobject[%p].\n", Object ); --nums if (object) (Objects_.erase) (Object->key ()); 65} 6 6 Delete object; Std::map<string, boost::weak_ptr<object> > Objects_; 70}; Namespace Version2 (objectpool:public)-boost::enable_shared_from_this<objectpool> PUBLIC:80 boost::shared_ptr<object> Get (const string& key) Bayi {TheSt::shared_ptr<object> Pobject; boost::weak_ptr<object>& k_object = Objects_[key]; Pobject = K_object.lock ();             if (!pobject) (++nums), Boost_assert (Nums <= maxnum); 89 Pobject.reset (New Object (key), Boost::bind (&objectpool::releaseobject, Shared_from_this ( ), _1)); K_object = Pobject; Pobject}; 94} private:97 void Releaseobject (Object* object) 98 {in printf ("releaseobject[%p].\n", Object         ); 104 if (object) 101 {102--nums;103 Objects_.erase (Object->key ()); }105 Delete object;106}107 108 std::map<string, boost::weak_ptr<object> > objects_;109};110 111}112 113 int Main () () + boost::shared_ptr<version1::objectpool> OP1 (new Version1::objectpool); 117 11 8 Boost::shared_ptr<object> Object1 = Op1->get ("Object1"); 119 boost::shared_ptr<object> Object2 = Op1->get ("Object2"); boost::s hared_ptr<object> object3 = Op1->get ("Object3"); 121 boost::shared_ptr<object> Object4 = Op1->get ("O Bject4 "); 122 boost::shared_ptr<object> object5 = Op1->get (" Object5 "); 123 boost::shared_ptr<object> OBJECT6 = Op1->get ("Object5"); 124//boost::shared_ptr<version2::objectpool> OP2 (New Version2::o Bjectpool); 126//boost::shared_ptr<object> object7 = Op2->get ("Object2"); 127//boost::shared_ptr<objec t> object8 = Op2->get ("Object2"); 129 return 0;130}131//output133 Construct object[003e1060] object1.1 Construct object[003e10e0] object2.135 Construct object[003e1160] object3.136 Construct object[003e11e0] object4.137 Construct object[003e1260] object5.138 releaseobject[003e1260].139 ~destruct object[003e1260] object5.140 releaseobject[003e11e0].141 ~destruct Object[003e11E0] object4.142 releaseobject[003e1160].143 ~destruct object[003e1160] object3.144 releaseobject[003e10e0].145 ~ Destruct object[003e10e0] object2.146 releaseobject[003e1060].147 ~destruct object[003e1060] Object1.

References

Https://en.wikipedia.org/wiki/Object_pool_pattern

Design of the object pool

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.