資源分配管理器
STL容器
我們將使用下面的容器來實現本文的例子:
queue |
隊列容器支持添加一個元素,并且從中刪除一個元素,也可以變成一個雙端隊列 |
priority_queue |
向隊尾添加一個新元素,如果該優先權大于前面的元素,將放在前面,元素的優先權由用戶指定的函數傳入。 |
stack |
有后進先出的特點,可以選擇選擇vetctor或其他線性列表放入容器。 |
1.消息隊列
消息隊列是項目中經常需要使用的模式,下面使用STL的queue容器實現:
#include // STL header file for queue #include using namespace std; // Specify that we are using the std namespace class Message; class Message_Queue { typedef queue > MsgQueType; MsgQueType m_msgQueue; public: void Add(Message *pMsg) { // Insert the element at the end of the queue m_msgQueue.push(pMsg); } Message *Remove() { Message *pMsg = NULL; // Check if the message queue is not empty if (!m_msgQueue.empty()) { // Queue is not empty so get a pointer to the // first message in the queue pMsg = m_msgQueue.front(); // Now remove the pointer from the message queue m_msgQueue.pop(); } return pMsg; } int GetLength() const { return m_msgQueue.size(); } };
2.優先級消息隊列
上面的消息隊列類只支持在隊列的尾部添加一個元素,在許多的應用程序中,需要根據消息的優先級將消息添加到隊列中,當一個高優先級的消息來了,需要將該消息添加到所有比它優先級低的消息前面,下面將使用priority_queue來實現優先級消息隊列類。
函數對象(Functors)
優先級消息隊列的實現和上面消息隊列實現相似,唯一不同的是這里使用了函數對象來決定優先權CompareMessages,該結構重載了操作符"(,)",該機制可以實現可以將一個函數作為一個參數,和函數指針對比有如下好處:
1.函數對象消息更高,可以是內聯函數,函數指針總是有函數調用的開銷。
2.函數對象提供了一個安全的實現方法,這樣的實現不會出現空指針訪問。
#include // STL header file for queue #include using namespace std; // Specify that we are using the std namespace class Message; class Priority_Message_Queue { struct Entry { Message *pMsg; int priority; }; struct Compare_Messages { bool operator () (const Entry& left , const Entry& right) { return (left.priority < right.priority); } }; typedef priority_queue, Compare_Messages > Message_Queue_Type; Message_Queue_Type m_message_Queue; public: void Add(Message *pMsg, int priority) { // Make an entry Entry entry; entry.pMsg = pMsg; entry.priority = priority; // Insert the element according to its priority m_message_Queue.push(entry); } Message *Remove() { Message *pMsg = NULL; // Check if the message queue is not empty if (!m_message_Queue.empty()) { // Queue is not empty so get a pointer to the // first message in the queue pMsg = (m_message_Queue.top()).pMsg; // Now remove the pointer from the message queue m_message_Queue.pop(); } return (pMsg); } size_t Get_Length() const { return m_message_Queue.size(); } };
3.資源分配管理器
這里使用queue 和 stack兩個容器來實現一個簡單的資源分配器,用該容器來保存空閑的資源列表。
該資源分配器支持如下接口:
1.Construction:當這個資源分配器構造出來,需要給定空閑的資源列表,這些資源將添加到這個空閑資源列表。
2.Allocate:當需要一個資源時,需要從空閑資源隊列中移除一個資源,并返回給調用者。
3.Free:當一個資源被釋放,需要將該資源加入空閑資源列表。
4.GetFreeResourceCount:返回當前可用的資源數目。
Coldest First(使用queue)
#include // STL header file for queue #include using namespace std; // Specify that we are using the std namespace class Resource; class Cold_Resource_Allocator { typedef queue > Free_Queue_Type; Free_Queue_Type m_free_Resource_Queue; public: Cold_Resource_Allocator(int resource_Count, Resource *resource_Array[]) { for (int i = 0; i < resource_Count; i++) { m_free_Resource_Queue.push(resource_Array[i]); } } Resource * Allocate() { Resource *pResource = NULL; // Check if any free resources are available. if (!m_free_Resource_Queue.empty()) { // Queue is not empty so get a pointer to the // first resource in the queue pResource = m_free_Resource_Queue.front(); // Now remove the pointer from the free resource queue m_free_Resource_Queue.pop(); } return pResource; } void Free(Resource *pResource) { // Insert the resource at the end of the free queue m_free_Resource_Queue.push(pResource); } size_t GetFreeResourceCount() { return m_free_Resource_Queue.size(); } };
Hottest First(使用statck)
#include // STL header file for stack #include using namespace std; // Specify that we are using the std namespace class Resource; class Hot_Resource_Allocator { typedef stack > Free_Stack_Type; Free_Stack_Type m_free_Resource_Stack; public: Hot_Resource_Allocator(int resource_Count, Resource *resource_Array[]) { for (int i = 0; i < resource_Count; i++) { m_free_Resource_Stack.push(resource_Array[i]); } } Resource * Allocate() { Resource *pResource = NULL; // Check if any free resources are available. if (!m_free_Resource_Stack.empty()) { // Queue is not empty so get a pointer to the // first resource in the stack pResource = m_free_Resource_Stack.top(); // Now remove the pointer from the free resource stack m_free_Resource_Stack.pop(); } return pResource; } void Free(Resource *pResource) { // Insert the resource at the end of the free stack m_free_Resource_Stack.push(pResource); } size_t GetFreeResourceCount() { return m_free_Resource_Stack.size(); } };