ソフトウェアを開発し続けて早六年。 バグを憎んで人を憎まず。。 株式投資で脱サラをめざすITエンジニアのホームページ......
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
固定数のオブジェクトをプールするクラスです。
応用すれば、コネクションプールやスレッドプールが作れます。
#pragma once
#include <vector>
#include <queue>
#include <windows.h>

/**
* 固定数のインスタンスをプールするオブジェクトプール
*/

template<typename T> class FixedPoolManager{
typedef FixedPoolManager<T> THIS_CLASS;
typedef T* TARGET;
public:
FixedPoolManager(){
}
~FixedPoolManager(){
for(size_t i = 0; i < instances.size(); i++){
TARGET obj = instances[i];
delete obj;
}
}
void Init(unsigned int maxInstance){
for(unsigned int i = 0; i < maxInstance; i++){
TARGET obj = 
new T();
instances.push_back(obj);
activeInstances.push(obj);
}
}

class Pointer{
friend class THIS_CLASS;
Pointer(TARGET obj, THIS_CLASS* mgr){
manager = mgr;
instance = obj;
}
public:
Pointer(
const Pointer& obj){
(*
this) = obj;
}
Pointer& 
operator =(const Pointer& obj){
this->instance = obj.instance;
this->manager = obj.manager;
Pointer* p = 
const_cast<Pointer*>(&obj);
p->instance = 
NULL;
p->manager = 
NULL;
return *this;
}
Pointer(TARGET obj){
manager = 
NULL;
instance = obj;
}
~Pointer(){
if(manager != NULL && instance != NULL){
manager->ReleaseInstance(instance);
}
}
TARGET 
operator->(){
return instance;
}
bool IsNull(){
return !instance;
}
operator TARGET(){
return instance;
}
bool operator ==(TARGET p){
return instance == p;
}
bool operator !=(TARGET p){
return instance != p;
}
private:
TARGET instance;
THIS_CLASS*  manager;
};

Pointer GetInstance(){

if(!activeInstances.empty()){
TARGET obj = activeInstances.front();
activeInstances.pop();
return Pointer(obj, this);
}
return Pointer(NULL);
}
private:
void ReleaseInstance(TARGET obj){
activeInstances.push(obj);
}
private:
std::vector<TARGET> instances;
std::queue<TARGET> activeInstances;
};

/**
* インスタンスを取得できるまでWaitするインスタンスマネージャ
*/

template<typename MANAGER, typename INSTANCE_TYPE, DWORD dwWaitMilliseconds = 500class LockedInstanceManager : public MANAGER{
public:
INSTANCE_TYPE GetInstance(){
for(;;){
INSTANCE_TYPE& obj = MANAGER::GetInstance();
if(obj == NULL){
::Sleep(dwWaitMilliseconds);
}
else{
return obj;
}
}
}
};

↓テスト用コード
#define _WIN32_WINNT 0x0500
#include <iostream>
#include "./PoolManager.h"

static int count;
class TestCls{
public:
TestCls(){
number = count++;
}
int number;
};

typedef FixedPoolManager<TestCls>::Pointer TARGET;
typedef LockedInstanceManager<FixedPoolManager<TestCls>, TARGET> Manager;

void Print(TestCls* obj){
if(obj)
std::cout << obj->number << std::endl;
else
std::cout << 
"null" << std::endl;
}

Manager manager;
DWORD WINAPI ThreadFunc(PVOID){
TARGET ptr = manager.GetInstance();
Print(ptr);
::Sleep(
3000);
return 0;
}

void main(){
count = 
0;
manager.Init(
3);
for(int i = 0; i < 100; i++)
::QueueUserWorkItem(ThreadFunc, 
NULL, WT_EXECUTELONGFUNCTION);

std::cin.get();
}
スポンサーサイト

テーマ:プログラミング - ジャンル:コンピュータ


管理者にだけ表示を許可する
http://qnd.blog36.fc2.com/tb.php/22-8d986cc6
この記事にトラックバックする(FC2ブログユーザー)
// HOME // 
シャトー・フルール・ド・ジャン・ゲイ・レゼルヴ 2001
↑これ、お気に入りのワインです
毎日ペースで飲んでる中からの
厳選(?)チョイスする予定。。
(ちなみに赤が好き)
カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム
ブログ内検索

RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。