19、基于共享内存的内存池

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


        作为技术性尝试,我在较新的机型上实现了基于共享内存的内存池,可以直接使用STL。

不过由于种种原因,其实没什么实用性(我那时候也是太闲)。

        这个东西和之前的共享内存其实是两条路线,完全可以用系统函数来重写底层。

目录

一、Allocator

二、共享内存池

2.1头信息,入口点

2.2头信息,空闲链表

2.3头信息

2.4主体代码

2.5池定义

三、Allocator定义

四、应用到主要容器


一、Allocator

        STL容器其实还有个很少用的参数,Allocator,用来申请内存,自定义这个参数就可以把容器的内存分配改到共享内存里面。听起来很美,不过要正确使用,必须保证所有容器都使用了改造后的参数,而且,并不会改变容器申请内存的策略,共享内存还是充满了碎片。

二、共享内存池

        首先要有个池供Allocator使用:

2.1头信息,入口点

	//头信息,存储入口点
	class BinaryPoolEntry
	{
	public:
		long count_allocator;//分配的总数
		long count_deallocator;//释放的总数
		long entry_count;
		long max_entry_count;
		pair<sstring<32>, T_SHM_SIZE > name_handle[1024];//必须是max_entry_count
	public:
		BinaryPoolEntry() :count_allocator(0), count_deallocator(0), entry_count(0), max_entry_count(1024) {}//注意max_entry_count必须和定义一致
		long GetEntry(char const * name)const
		{
			long i;
			for (i = 0; i < entry_count; ++i)
			{
				if (name_handle[i].first == name)
				{
					return name_handle[i].second;
				}
			}
			return -1;
		}
		bool AddEntry(char const * name, long handle)
		{
			if (GetEntry(name) < 0)
			{
				if (entry_count == max_entry_count)
				{
					thelog << "入口点已满,无法存储" << ende;
					return false;
				}
				else
				{
					name_handle[entry_count].first = name;
					name_handle[entry_count].second = handle;
					++entry_count;
					return true;
				}
			}
			else
			{
				thelog << name << " 已经存在" << ende;
				return false;
			}
		}
		string & toString(string & ret)const
		{
			ret = "";

			char buf[256];
			long i;
			sprintf(buf, "总分配 %ld,总释放 %ld,最大入口点数 %ld,已用 %ld\n", count_allocator, count_deallocator, max_entry_count, entry_count);
			ret += buf;
			for (i = 0; i < entry_count; ++i)
			{
				sprintf(buf, "%ld : %32s %ld\n", i, name_handle[i].first.c_str(), name_handle[i].second);
				ret += buf;
			}
			return ret;
		}
	};

2.2头信息,空闲链表

	//头信息,存储空闲链表
	class BinaryPoolFreeList
	{
		enum { FREE_LIST_SIZE = 100 };
		struct _FreeList
		{
			T_SHM_SIZE unit;//分配的单元大小,0为未用
			T_SHM_SIZE handle;
			long size;
			_FreeList() :unit(0), handle(-1), size(0) {}
		};
	public:
		_FreeList freelist[FREE_LIST_SIZE];//必须等于max_list
		long max_list;//必须等于freelist数组大小
		BinaryPoolFreeList() :max_list(FREE_LIST_SIZE) {}//必须等于freelist数组大小
		//计算空闲链表位置,第0个存储没有位置存的,其余存储8的倍数的
		void calcFreeHandle(long n, long & _freelist, long & newsize)
		{
			_freelist = 0;
			newsize = n;
			if (0 != newsize % 8)newsize = 8 * (newsize / 8 + 1);
			if (newsize < 8)newsize = 8;

			for (long i = 1; i < max_list; ++i)
			{
				if (freelist[i].unit == newsize)
				{
					_freelist = i;
					return;
				}
				if (0 == freelist[i].unit)
				{
					freelist[i].unit = newsize;
					_freelist = i;
					return;
				}
			}
		}
		string & toString(string & ret)const
		{
			ret = "";

			char buf[256];
			long i;
			sprintf(buf, "空闲链表数 %ld\n", max_list);
			ret += buf;
			for (i = 0; i < max_list; ++i)
			{
				if (0 != i && 0 == freelist[i].unit && -1 == freelist[i].handle)continue;
				sprintf(buf, "%ld : %ldB %ld 个,h=%ld\n", i, freelist[i].unit, freelist[i].size, freelist[i].handle);
				ret += buf;
			}
			return ret;
		}
	};

2.3头信息

	class BinaryPoolHead
	{
	public:
		BinaryPoolEntry entry;
		BinaryPoolFreeList FreeList;
		string & toString(string & ret)const
		{
			string str;
			ret = "";
			ret += entry.toString(str);
			ret += "\n";
			ret += FreeList.toString(str);
			return ret;
		}
	};

2.4主体代码

	//共享内存池
	template<int PI_N>
	class BinaryPool : public T_ARRAY<char, PI_N, BinaryPoolHead >
	{
	private:
		using T_ARRAY<char, PI_N, BinaryPoolHead >::ReportHead;
		using T_ARRAY<char, PI_N, BinaryPoolHead >::GetHead;
		using T_ARRAY<char, PI_N, BinaryPoolHead >::size;
		using T_ARRAY<char, PI_N, BinaryPoolHead >::capacity;
		using T_ARRAY<char, PI_N, BinaryPoolHead >::Adds_block;
		using T_ARRAY<char, PI_N, BinaryPoolHead >::Add;
		using T_ARRAY<char, PI_N, BinaryPoolHead >::Reserve;
	public:
		using T_ARRAY<char, PI_N, BinaryPoolHead >::GetUserHead;
		typedef typename T_ARRAY<char, PI_N, BinaryPoolHead >::HANDLE HANDLE;
	public:
		BinaryPool(char const * name, int version = 0) :T_ARRAY<char, PI_N, BinaryPoolHead >(name, version) {}
		void Show(bool withhead = true, long startpos = 0, long maxcount = 32 * 8)const
		{
			string str;
			str = "";
			if (startpos < 0)
			{
				thelog << "错误的起始位置 " << startpos << " 默认为0" << ende;
				startpos = 0;
			}
			if (withhead)thelog << endl << ReportHead(str) << endl << " 开始报告共享内存池" << " ......" << endl;
			else thelog << endl;
			if (NULL != GetHead())
			{
				T_SHM_SIZE i;
				char const * last = NULL;
				HANDLE h;
				long tmplong;//记录一个long
				theLog << "起始位置 " << startpos << " 总大小 " << GetHead()->size << endl;
				for (i = startpos; i < GetHead()->size; ++i)
				{
					h.handle = i;
					last = this->Get(h);
					((char *)&tmplong)[i % 8] = *last;
					if (i < startpos + maxcount)
					{
						char buf[1024];
						if (0 == i % 8)
						{
							sprintf(buf, "%3ld :", i);
							theLog << buf;
						}
						char buf2[256];
						sprintf(buf2, "%02X", *last);
						if (strlen(buf2) > 2)memmove(buf2, buf2 + strlen(buf2) - 2, 3);//LINUX好好有趣哦
						sprintf(buf, " %s %4d %c", buf2, *last, (isprint(*last) ? *last : ' '));
						theLog << buf;
						if (0 == (i + 1) % 8)
						{
							str = "";
							for (long j = 0; j < 8; ++j)
							{
								unsigned char c = ((unsigned char *)&tmplong)[j];
								if (c >= ' ' && c < 127)
								{
									str += c;
								}
								else if (c > 127 && c < 255)
								{
									if (j < 7 && ((unsigned char *)&tmplong)[j + 1]>127)
									{
										str += c;
										str += ((unsigned char *)&tmplong)[j + 1];
										++j;
									}
									else
									{
										str += '.';
									}
								}
								else if (127 == c)
								{
									str += ".";
								}
								else
								{
									str += ".";
								}
							}
							theLog << " | " << str;
							sprintf(buf, " | %016lX %ld", tmplong, tmplong);
							theLog << buf << endl;
						}
					}
					else
					{
						break;
					}
				}
				theLog << "下一个位置 " << i << " 剩余字节数 " << GetHead()->size - i << endl;
			}
			theLog << endi;
		}
		void view()const
		{
			string cmd;
			long startpos = 0;
			long maxline = 32;
			while (true)
			{
				cmd = UIInput("共享内存显示 enter=继续显示 num=起始位置 max=设置每次显示的行数 b=break", "");
				if ("" == cmd)
				{
					if (startpos >= GetHead()->size)
					{
						thelog << "已经到达结尾" << endi;
						startpos = GetHead()->size;
					}
					Show((0 == startpos), startpos, maxline * 8);
					startpos += maxline * 8;
				}
				else if ("max" == cmd)
				{
					maxline = atol(UIInput("请输入行数", "").c_str());
					if (maxline < 8)
					{
						thelog << "输入不能小于8,已经设置为8" << ende;
						maxline = 8;
					}
					thelog << "maxline=" << maxline << endi;
				}
				else if ("b" == cmd)
				{
					break;
				}
				else
				{
					startpos = atol(cmd.c_str());
					if (0 != startpos % 8)
					{
						thelog << "起始位置必须是8的倍数" << ende;
						startpos = (startpos / 8) * 8;
						thelog << "已经重设为 " << startpos << endi;
					}
					Show((0 == startpos), startpos, maxline * 8);
					startpos += maxline * 8;
				}
			}
		}
		bool _Allocate(long n, HANDLE & h)
		{
			if (BINARYPOOL_Not_MakeShmData)
			{
				thelog << "仅可在构造共享内存池数据时调用" << ende;
				return false;
			}
			if (0 == size())
			{
				if (BINARYPOOL_TRANCE)thelog << "由于池为空,先申请8字节填充HANDLE为0的位置" << endi;
				HANDLE h;
				if (!Adds_block("NULLNULL", 8, h))
				{
					thelog << "内存不足" << ende;
					return false;
				}
			}
			else
			{
				if (BINARYPOOL_TRANCE)thelog << "池size " << size() << endi;
			}
			//检查剩余空间是否足够,若不够将剩余空间用0填充,避免一个字符串存储到两个块
			//共享内存增长大小应该确保大于最长的字符串
			T_SHM_SIZE i;
			HANDLE tmph;
			T_SHM_SIZE tmpn;//实际申请的大小
			long freelist;//空闲链表位置
			GetUserHead()->FreeList.calcFreeHandle(n, freelist, tmpn);
			if (BINARYPOOL_TRANCE)thelog << "n=" << n << " freelist=" << freelist << " newsize=" << tmpn << endi;
			//首先试图从空闲链表中分配
			BinaryPoolHead * pHead = GetUserHead();
			if (freelist != 0)
			{
				if (pHead->FreeList.freelist[freelist].size > 0)
				{
					h.handle = pHead->FreeList.freelist[freelist].handle;
					tmph.handle = pHead->FreeList.freelist[freelist].handle;
					pHead->FreeList.freelist[freelist].handle = *(long *)&*tmph;
					--pHead->FreeList.freelist[freelist].size;

					if (BINARYPOOL_TRANCE)thelog << "Allocate " << n << "(" << tmpn << ") " << h.handle << " from freelist" << endi;
					GetUserHead()->entry.count_allocator += n;
					return true;
				}
			}
			else
			{
			}

			//加入字符串--------------------------这一段有问题,考虑直接使用Adds_block
			if (static_cast<long>(capacity() - size()) < tmpn)
			{
				while (size() < capacity())Add('\0', tmph);
				if (!Reserve(size() + tmpn, tmpn))
				{
					thelog << "内存不足" << ende;
					return false;
				}
			}
			for (i = 0; i < tmpn; ++i)
			{
				if (!Add('\0', tmph))return false;
				if (0 == i)h = tmph;
			}
			if (BINARYPOOL_TRANCE)thelog << "Allocate " << n << "(" << tmpn << ") " << h.handle << endi;
			GetUserHead()->entry.count_allocator += n;
			return true;
		}
		bool Allocate(long n, HANDLE & h)
		{
			if (!_Allocate(n + sizeof(long), h))return false;
			*(long *)&*h = n;
			h.handle += sizeof(long);
			return true;
		}
		bool _Deallocate(HANDLE const & _h, long n)
		{
			HANDLE h = _h;
			BinaryPoolHead * pHead = GetUserHead();

			T_SHM_SIZE tmpn;//实际申请的大小
			long freelist;//空闲链表位置
			GetUserHead()->FreeList.calcFreeHandle(n, freelist, tmpn);
			if (BINARYPOOL_TRANCE)thelog << "Deallocate n=" << n << " freelist=" << freelist << " newsize=" << tmpn << " h=" << _h.handle << endi;
			for (long i = 0; i < tmpn; ++i, ++h)
			{
				*h = 0xE3;
			}

			if (0 != freelist)
			{
				*(long *)&*_h = pHead->FreeList.freelist[freelist].handle;
				pHead->FreeList.freelist[freelist].handle = _h.handle;
				++pHead->FreeList.freelist[freelist].size;
			}
			else
			{
				*(long *)&*_h = pHead->FreeList.freelist[freelist].handle;
				((long *)&*_h)[1] = tmpn;//下一个long存储长度
				pHead->FreeList.freelist[freelist].handle = _h.handle;
				++pHead->FreeList.freelist[freelist].size;
			}

			GetUserHead()->entry.count_deallocator += n;
			return true;
		}
		bool Deallocate(HANDLE const & _h, long n)
		{
			if (BINARYPOOL_Not_MakeShmData)
			{
				thelog << "仅可在构造共享内存池数据时调用" << ende;
				return false;
			}

			HANDLE h;
			h.handle = _h.handle - sizeof(long);
			if (n != *(long *)&*h)
			{
				throw "Deallocate n error";
			}
			return _Deallocate(h, *(long *)&*h + sizeof(long));
		}
		bool Deallocate(HANDLE const & _h)
		{
			if (BINARYPOOL_Not_MakeShmData)
			{
				thelog << "仅可在构造共享内存池数据时调用" << ende;
				return false;
			}

			HANDLE h;
			h.handle = _h.handle - sizeof(long);
			return _Deallocate(h, *(long *)&*h + sizeof(long));
		}
		long GetUserLen(HANDLE const & _h)
		{
			HANDLE h;
			h.handle = _h.handle - sizeof(long);
			return *(long *)&*h;
		}

		HANDLE GetEntry(char const * name)const
		{
			HANDLE h;
			h.handle = GetUserHead()->entry.GetEntry(name);
			return h;
		}
		bool AddEntry(char const * name, HANDLE handle)
		{
			if (BINARYPOOL_Not_MakeShmData)
			{
				thelog << "仅可在构造共享内存池数据时调用" << ende;
				return false;
			}
			return GetUserHead()->entry.AddEntry(name, handle.handle);
		}
		template<typename Y >
		Y * NEW()
		{
			HANDLE h;
			if (!Allocate(sizeof(Y), h))return NULL;
			else
			{
				new((Y*)&*h) Y;
				return (Y*)&*h;
			}
		}
		template<typename Y >
		Y * GetEntryWithNewIfNeed(char const * name)
		{
			HANDLE h = GetEntry(name);
			if (h.handle < 0)
			{
				thelog << "入口点 " << name << " 不存在,需要添加" << endi;
				if (!Allocate(sizeof(Y), h))return NULL;
				else
				{
					if (!AddEntry(name, h))
					{
						thelog << "添加入口点 " << name << " 出错" << ende;
						Deallocate(h, sizeof(Y));
						return NULL;
					}
					new((Y*)&*h) Y;
					return (Y*)&*h;
				}
			}
			else
			{
				return (Y*)&*h;
			}
		}
	public:
		virtual bool disableMutex()const { return true; }
		virtual bool Report()const
		{
			Show();
			return true;
		}
		virtual bool ExportTextToDir(char const * dir_name)const
		{
			thelog << "共享内存池不需要导出文本" << endi;
			return true;
		}
		virtual bool ToDo(char const * what)
		{
			if (NULL == what || '\0' == what[0])
			{
			}
			else if (0 == strcmp(what, "view"))
			{
				view();
			}
			else
			{
			}
			thelog << "ToDo: view" << endi;
			return true;
		}
	};

2.5池定义

        因为只有一个池,直接定义了:

	typedef BinaryPool<PI_SHMPOOL > _ShmPool;

	class ShmPool : public _ShmPool
	{
		DECLARE_SINGLETON(ShmPool);
	public:
		ShmPool() :_ShmPool(SHM_NAME_SHMPOOL, 0) {}
	};

三、Allocator定义

	template<typename T>
	class ShmAllocator
	{
	private:
	public:
		typedef T value_type;
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
		typedef T * pointer;
		typedef T const * const_pointer;
#else
		class shm_pointer
		{
		public:
#ifdef _LINUX_CC
			typedef random_access_iterator_tag iterator_category;
#endif

			typedef T * pointer;
			typedef T element_type;
			typedef T value_type;
			typedef long difference_type;
			typedef long offset_type;
			typedef T & reference;
			template<typename U>
			struct rebind : public ShmAllocator<U>::shm_pointer {};
		public:
			T_SHM_SIZE handle;
			shm_pointer() :handle(0) {}
			shm_pointer(ShmPool::HANDLE const & h) :handle(h.handle) {}
			shm_pointer(T * p)
			{
				if (NULL == p)handle = 0;
				else handle = ShmPool::HANDLE::_me((char *)p, true);
				//if (handle < 0)throw "非法句柄";
			}
			//static shm_pointer pointer_to(T & tmp) { return const_shm_pointer(); }
			static shm_pointer pointer_to(T & tmp) { return shm_pointer(tmp); }

			shm_pointer operator + (long n)const { return shm_pointer(handle + n * sizeof(T)); }
			shm_pointer operator - (long n)const { return shm_pointer(handle - n * sizeof(T)); }
			bool operator < (shm_pointer const & tmp)const { return handle < tmp.handle; }
			T_SHM_SIZE operator - (shm_pointer const & tmp)const { return (handle - tmp.handle) / sizeof(T); }
			shm_pointer & operator += (T_SHM_SIZE n) { handle += n * sizeof(T); return *this; }
			shm_pointer & operator ++ () { operator +=(1); return *this; }
			shm_pointer & operator -- () { operator +=(-1); return *this; }
			shm_pointer & operator ++ (int) { shm_pointer tmp = *this; operator +=(1); return tmp; }
			shm_pointer & operator -- (int) { shm_pointer tmp = *this; operator +=(-1); return tmp; }
			shm_pointer & operator = (shm_pointer const & tmp) { handle = tmp.handle; return *this; }
			bool operator == (T const * p)const { return *this == shm_pointer((T *)p); }
			bool operator != (T const * p)const { return *this != shm_pointer((T *)p); }
			bool operator == (shm_pointer const & tmp)const { return handle == tmp.handle; }
			bool operator != (shm_pointer const & tmp)const { return !((*this) == tmp); }

			T & operator * ()const { return *operator ->(); }
			T * operator -> ()const { if (0 == handle)return NULL; else return (T *)&* ShmPool::HANDLE(handle); }
			operator T *() { return operator ->(); }
		};
		class const_shm_pointer
		{
		public:
#ifdef _LINUX_CC
			typedef random_access_iterator_tag iterator_category;
#endif

			typedef T const * pointer;
			typedef T const element_type;
			typedef T const value_type;
			typedef long difference_type;
			typedef long offset_type;
			typedef T const & reference;
			template<typename U>
			struct rebind : public ShmAllocator<U>::const_shm_pointer {};

		public:
			T_SHM_SIZE handle;
			const_shm_pointer() :handle(0) {}
			const_shm_pointer(ShmPool::HANDLE const & h) :handle(h.handle) {}
			const_shm_pointer(const_shm_pointer const & tmp) :handle(tmp.handle) {}
			const_shm_pointer(shm_pointer const & tmp) :handle(tmp.handle) {}
			const_shm_pointer(T const * p)
			{
				if (NULL == p)handle = 0;
				else handle = ShmPool::HANDLE::_me((char const *)p, true);
				//if (handle < 0)throw "非法句柄";
			}
			//static pointer pointer_to(T const & tmp) { return pointer((T*)(void*)&tmp); }
			static const_shm_pointer pointer_to(T const & tmp) { return const_shm_pointer(tmp); }

			const_shm_pointer operator + (long n)const { return const_shm_pointer(handle + n * sizeof(T)); }
			const_shm_pointer operator - (long n)const { return const_shm_pointer(handle - n * sizeof(T)); }
			bool operator < (const_shm_pointer const & tmp)const { return handle < tmp.handle; }
			T_SHM_SIZE operator - (const_shm_pointer const & tmp)const { return (handle - tmp.handle) / sizeof(T); }
			const_shm_pointer & operator += (T_SHM_SIZE n) { handle += n * sizeof(T); return *this; }
			const_shm_pointer & operator ++ () { operator +=(1); return *this; }
			const_shm_pointer & operator -- () { operator +=(-1); return *this; }
			const_shm_pointer & operator ++ (int) { const_shm_pointer tmp = *this; operator +=(1); return tmp; }
			const_shm_pointer & operator -- (int) { const_shm_pointer tmp = *this; operator +=(-1); return tmp; }
			const_shm_pointer & operator = (const_shm_pointer const & tmp) { handle = tmp.handle; return *this; }
			bool operator == (T const * p)const { return *this == const_shm_pointer((T *)p); }
			bool operator != (T const * p)const { return *this != const_shm_pointer((T *)p); }
			bool operator == (const_shm_pointer const & tmp)const { return handle == tmp.handle; }
			bool operator != (const_shm_pointer const & tmp)const { return !((*this) == tmp); }

			T const & operator * ()const { return *operator ->(); }
			T const * operator -> ()const { if (0 == handle)return NULL; else return (T const *)&* ShmPool::HANDLE(handle); }
			operator T const *() { return operator ->(); }
		};
#endif
		typedef T & reference;
		typedef T const & const_reference;
		typedef ptrdiff_t difference_type;
		typedef shm_pointer pointer;
		typedef const_shm_pointer const_pointer;
		typedef long size_type;
		/*重绑定函数*/
		template<typename U>
		struct rebind
		{
			typedef ShmAllocator < U > other;
		};
		ShmAllocator() throw () {}
		ShmAllocator(ShmAllocator const &) throw () {}
		template<typename U>
		ShmAllocator(ShmAllocator < U > const &) throw () {}
		//若一个分配的空间可由另一个返还则相等
		template<typename U>
		bool operator == (ShmAllocator<U> const &) throw ()
		{
			thelog << "operator ==" << endi;
			return true;
		}
		/* 申请内存*/
		pointer allocate(size_type num, void * hint = 0)
		{
			if (BINARYPOOL_TRANCE)thelog << "申请 " << num << "  个内存块,sizeof(T)=" << sizeof(T) << endi;
			if (BINARYPOOL_Not_MakeShmData)
			{
				if (BINARYPOOL_TRANCE)thelog << "非构造共享内存池数据,由私有内存分配" << endi;
				std::allocator<T> stdallocator;
				return stdallocator.allocate(num, hint);
			}
			ShmPool::HANDLE h;
			if (!ShmPool::getInstPtr()->Allocate(num * sizeof(T), h))
			{
				thelog << "内存不足" << ende;
				return pointer(0);
			}
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
			pointer ptr((T *)(void *)&*h);
			if (BINARYPOOL_TRANCE)thelog << ptr << endi;
#else
			pointer ptr(h);
			if (BINARYPOOL_TRANCE)thelog << ptr.handle << endi;
#endif
			return ptr;
		}
		/* 释放内存 */
		void deallocate(pointer p, size_type num)
		{
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
			if (BINARYPOOL_TRANCE)thelog << "在 " << (long)p << " 释放 " << num << "  个内存块,sizeof(T)=" << sizeof(T) << endi;
#else
			if (BINARYPOOL_TRANCE)thelog << "在 " << p.handle << " 释放 " << num << "  个内存块,sizeof(T)=" << sizeof(T) << endi;
#endif
			if (BINARYPOOL_Not_MakeShmData)
			{
				if (BINARYPOOL_TRANCE)thelog << "非构造共享内存池数据,由私有内存释放" << endi;
				std::allocator<T> stdallocator;
				return stdallocator.deallocate(p, num);
			}
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
			if (NULL == p || 0 == num)
#else
			if (0 == p.handle || 0 == num)
#endif
			{
				//thelog<<"在 "<<(long)p<<" 释放 "<<num<<"  个内存块,sizeof(T)="<<sizeof(T)<<" 已忽略"<<endi;
				return;
			}
			ShmPool::HANDLE h;
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
			h.handle = ShmPool::HANDLE::_me((char const *)p, true);
#else
			h.handle = p.handle;
#endif
			if (!ShmPool::getInstPtr()->Deallocate(h, num * sizeof(T)))throw "释放内存失败";
		}
		size_type max_size() const throw()
		{
			return 0xEFFFFFFFFFFFFFFF;
		}
		/* 使用placement new创建对象 */
		void construct(pointer p, const_reference value)
		{
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
			if (BINARYPOOL_TRANCE)thelog << "construct " << (long)p << endi;
#else
			if (BINARYPOOL_TRANCE)thelog << "construct " << p.handle << endi;
#endif
			new((void *)&*p) T(value); //placement new
		}
		/* 销毁对象 */
		void destroy(pointer p)
		{
#ifdef SHM_ALLOCATOR_USE_OLD_POINTER
			if (BINARYPOOL_TRANCE)thelog << "destroy " << (long)p << endi;
#else
			if (BINARYPOOL_TRANCE)thelog << "destroy " << p.handle << endi;
#endif
			((T*)(void *)&*p)->~T();
		}
		pointer address(reference value) const
		{
			if (BINARYPOOL_TRANCE)thelog << "address" << endi;
			return &value;
		}
		const_pointer address(const_reference value) const
		{
			if (BINARYPOOL_TRANCE)thelog << "address" << endi;
			return &value;
		}
		~ShmAllocator() throw () {}
	};

四、应用到主要容器

	typedef std::basic_string<char, std::char_traits<char>, ShmAllocator<char> > shm_string;
	template <typename T>
	class shm_vector : public vector<T, ShmAllocator<T > > {};
	template <typename T>
	class shm_set : public set<T, less<T >, ShmAllocator<T > > {};
	template <typename K, typename D>
	class shm_map : public map < K, D, less<K >, ShmAllocator<pair<const K, D> > > {};

        主要的容器就是这样了。注意容器本身也要放在共享内存里面。


(这里是结束)

相关推荐

  1. 19基于共享内存

    2024-07-23 10:24:04       40 阅读
  2. 12、实现基于共享二叉树set(续)

    2024-07-23 10:24:04       29 阅读
  3. linux内核原理-共享,信号

    2024-07-23 10:24:04       33 阅读
  4. DGPU共享问题

    2024-07-23 10:24:04       23 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-23 10:24:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-23 10:24:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-07-23 10:24:04       87 阅读
  4. Python语言-面向对象

    2024-07-23 10:24:04       97 阅读

热门阅读

  1. Hisilicon适配按键

    2024-07-23 10:24:04       42 阅读
  2. qml实现双指左右滑动,上下滑动

    2024-07-23 10:24:04       39 阅读
  3. LeetCode 算法:分割回文串 c++

    2024-07-23 10:24:04       40 阅读
  4. 【力扣每日一题】

    2024-07-23 10:24:04       39 阅读
  5. JVM类加载机制详解

    2024-07-23 10:24:04       37 阅读
  6. Python:字典(Dictionary)基础应用

    2024-07-23 10:24:04       29 阅读
  7. 数据结构C++——矩阵【详】

    2024-07-23 10:24:04       32 阅读
  8. 问百度文心一言 下三角矩阵

    2024-07-23 10:24:04       29 阅读
  9. cookie和session的区别

    2024-07-23 10:24:04       29 阅读
  10. 图像预处理(基础功能)

    2024-07-23 10:24:04       31 阅读
  11. 014集——RSA非对称加密——vba源代码

    2024-07-23 10:24:04       32 阅读
  12. 如何面对压力和动力

    2024-07-23 10:24:04       36 阅读