最近看操作系统写个Dijkstra银行家算法

来源:互联网 发布:ubuntu安装教程u盘 编辑:程序博客网 时间:2024/05/31 20:52

#pragma warning(disable:4786)
#include <iostream>
#include <string>
#include <list>
#include <map>
using namespace std;

typedef int RESCOUNTTYPE;


typedef map<string, RESCOUNTTYPE> ResCountmap;
typedef ResCountmap::iterator ResCountmapIt;

class ResCountMap
{
public:
    void Add(string strName, RESCOUNTTYPE count);
    void Print();
    void DelteAll();

    ResCountmap m_ResCountmap;

};

void ResCountMap::Add(string strName, RESCOUNTTYPE count)
{
    m_ResCountmap.insert(make_pair(strName, count));
}

void ResCountMap::Print()
{
    ResCountmapIt it = m_ResCountmap.begin();
    for (; it != m_ResCountmap.end(); it ++)
    {
        cout<<it->first<<"  "<<it->second<<endl;
    }
}

void ResCountMap::DelteAll()
{
    m_ResCountmap.clear();
}

struct ConsumeProcessNode
{
public:
    ConsumeProcessNode(string strName, const ResCountMap& OwnResLst,
        const ResCountMap& RequestTotalLst)
    {
        m_strname = strName;
        m_OwnRes = OwnResLst;
        m_RequestTotalRes = RequestTotalLst;
        m_bIsFinish = false;
    }

    string m_strname;
    ResCountMap m_OwnRes;
    ResCountMap m_RequestTotalRes;
    bool m_bIsFinish;
};

typedef list<ConsumeProcessNode> ConsumeProcessLst;
typedef ConsumeProcessLst::iterator ConsumeProcessIt;

class ConsumeProcessList
{
public:
    void Add(const ConsumeProcessNode &Value);
    void Add(string strName, const ResCountMap& OwnResLst,
        const ResCountMap& RequestTotalLst);
    void Print();
    void DeleteAll();
    bool IsAllFinish();

    ConsumeProcessLst m_ConsumeProcessLst;

};

void ConsumeProcessList::Add(const ConsumeProcessNode &Value)
{
    m_ConsumeProcessLst.push_back(Value);
}

void ConsumeProcessList::Add(string strName, const ResCountMap& OwnResLst,
                             const ResCountMap& RequestTotalLst)
{
    ConsumeProcessNode Node(strName, OwnResLst, RequestTotalLst);
    m_ConsumeProcessLst.push_back(Node);
}

void ConsumeProcessList::DeleteAll()
{
    m_ConsumeProcessLst.clear();
}

void ConsumeProcessList::Print()
{
    ConsumeProcessIt processit;
    for (processit = m_ConsumeProcessLst.begin(); processit !=
        m_ConsumeProcessLst.end(); processit ++)
    {
        cout<<processit->m_strname<<"        "<<endl;

        ResCountmapIt rescountit;
        for (rescountit = processit->m_RequestTotalRes.m_ResCountmap.begin();
        rescountit != processit->m_RequestTotalRes.m_ResCountmap.end(); rescountit ++)
        {
            cout<<rescountit->first<<"  "<<rescountit->second<<"  ";
        }

        cout<<endl;

        for (rescountit = processit->m_OwnRes.m_ResCountmap.begin();
        rescountit != processit->m_OwnRes.m_ResCountmap.end(); rescountit ++)
        {
            cout<<rescountit->first<<"  "<<rescountit->second<<"  ";

        }
        cout<<endl;
    }
}

bool ConsumeProcessList::IsAllFinish()
{
    ConsumeProcessIt it = m_ConsumeProcessLst.begin();
    for (; it != m_ConsumeProcessLst.end(); it ++)
    {
        if (!(it->m_bIsFinish))
        {
            return false;
        }
    }
    return true;
}

class Banker
{
public:
    void Init();
    void Print();
    bool GetSafeSequence();
private:
    ConsumeProcessList m_ConsumeLst;
    ResCountMap m_AllResLst;
    ResCountMap m_AvailableLst;
};

void Banker::Init()
{
    // Process0
    ResCountMap MaxRes;
    ResCountMap AllocationRes;
    MaxRes.Add("ResA", 9);
    MaxRes.Add("ResB", 5);
    MaxRes.Add("ResC", 3);

    AllocationRes.Add("ResA", 0);
    AllocationRes.Add("ResB", 1);
    AllocationRes.Add("ResC", 0);

    m_ConsumeLst.Add("ConsumeProcess0", AllocationRes, MaxRes);
    MaxRes.DelteAll();
    AllocationRes.DelteAll();

    // Process1
    MaxRes.Add("ResA", 3);
    MaxRes.Add("ResB", 2);
    MaxRes.Add("ResC", 2);
   
    AllocationRes.Add("ResA", 2);
    AllocationRes.Add("ResB", 0);
    AllocationRes.Add("ResC", 0);
   
    m_ConsumeLst.Add("ConsumeProcess1", AllocationRes, MaxRes);
    MaxRes.DelteAll();
    AllocationRes.DelteAll();

    // Process2
    MaxRes.Add("ResA", 9);
    MaxRes.Add("ResB", 0);
    MaxRes.Add("ResC", 2);
   
    AllocationRes.Add("ResA", 3);
    AllocationRes.Add("ResB", 0);
    AllocationRes.Add("ResC", 2);
   
    m_ConsumeLst.Add("ConsumeProcess2", AllocationRes, MaxRes);
    MaxRes.DelteAll();
    AllocationRes.DelteAll();

    // Process3
    MaxRes.Add("ResA", 2);
    MaxRes.Add("ResB", 2);
    MaxRes.Add("ResC", 2);
   
    AllocationRes.Add("ResA", 2);
    AllocationRes.Add("ResB", 1);
    AllocationRes.Add("ResC", 1);
   
    m_ConsumeLst.Add("ConsumeProcess3", AllocationRes, MaxRes);
    MaxRes.DelteAll();
    AllocationRes.DelteAll();

    // Process4
    MaxRes.Add("ResA", 4);
    MaxRes.Add("ResB", 3);
    MaxRes.Add("ResC", 3);
   
    AllocationRes.Add("ResA", 0);
    AllocationRes.Add("ResB", 0);
    AllocationRes.Add("ResC", 2);
   
    m_ConsumeLst.Add("ConsumeProcess4", AllocationRes, MaxRes);
    MaxRes.DelteAll();
    AllocationRes.DelteAll();

    // Resource
    m_AllResLst.Add("ResA",10);
    m_AllResLst.Add("ResB",5);
    m_AllResLst.Add("ResC",7);

    m_AvailableLst = m_AllResLst;

    // calc Available Resource
    ConsumeProcessIt it = m_ConsumeLst.m_ConsumeProcessLst.begin();
    for (; it != m_ConsumeLst.m_ConsumeProcessLst.end(); it ++)
    {
        ResCountmapIt resit = it->m_OwnRes.m_ResCountmap.begin();
        for (; resit != it->m_OwnRes.m_ResCountmap.end(); resit ++)
        {
            ResCountmapIt avaIt = m_AvailableLst.m_ResCountmap.find(resit->first);
            avaIt->second -= resit->second;
        }
    }
 }

void Banker::Print()
{
    m_ConsumeLst.Print();
    m_AllResLst.Print();
    m_AvailableLst.Print();
}

bool Banker::GetSafeSequence()
{
    bool bFind = true;
    bool bCanAllocation;
    ResCountmapIt resit;
    ResCountmapIt resRecoverIt;
    ConsumeProcessIt ProcessIt;

    while(1)
    {
        ConsumeProcessIt it = m_ConsumeLst.m_ConsumeProcessLst.begin();
        bFind = false;
        for (; it != m_ConsumeLst.m_ConsumeProcessLst.end(); it ++)
        {
            ProcessIt = it;
            if (it->m_bIsFinish)
            {
                continue;
            }
           
            bCanAllocation = true;
            resit = it->m_RequestTotalRes.m_ResCountmap.begin();
            for (; resit != it->m_RequestTotalRes.m_ResCountmap.end(); resit ++)
            {
                ResCountmapIt avaIt;
                avaIt = m_AvailableLst.m_ResCountmap.find(resit->first);
                if (avaIt->second < resit->second)
                {
                    bCanAllocation = false;
                    break;
                }
            }
            if (bCanAllocation)
            {
                bFind = true;
                break;
            }
        }

        if (bFind)
        {
            resRecoverIt = it->m_RequestTotalRes.m_ResCountmap.begin();
            for (; resRecoverIt != it->m_RequestTotalRes.m_ResCountmap.end(); resRecoverIt ++)
            {
                ResCountmapIt avaIt;
                avaIt = m_AvailableLst.m_ResCountmap.find(resRecoverIt->first);
                avaIt->second += resRecoverIt->second;
                it->m_bIsFinish = true;
            }
            cout<<it->m_strname<<endl;
            continue;
        }
        else
        {
            break;
        }
       
    }

    return m_ConsumeLst.IsAllFinish();
}

int main()
{
    Banker bank;
    bank.Init();
//    bank.Print();
    if (bank.GetSafeSequence())
    {
        cout<<"存在安全序列"<<endl;
    }
    else
    {
        cout<<"存在安全序列"<<endl;
    }

    return 0;
}

原创粉丝点击