// Keep the source author and other relevant information for any source code reprinted.
// Author: chlaws
// Running environment: Visual Studio 2008
// Description: Banker's algorithm and Demonstration Result
// Note: the original ideas are not provided here. If you do not know how to ask during reading
# Include <iostream> <br/> # include <cstdlib> <br/> # include <string> <br/> # include <iterator> <br/> # include <Algorithm> <br/> # include <vector> <br/> # include <cstdlib> <br/> using namespace STD; <br/> const int max = 5; <br/> class banker; <br/> class processinfo {<br/> Public: <br/> processinfo () <br/>{< br/> _ processname = ""; </P> <p> memset (_ allocation, 0, max ); <br/> memset (_ Need, 0, max); <br/> memset (_ work, 0, max ); <Br/> memset (_ tmpalloc, 0, max); <br/> memset (_ tmpneed, 0, max); </P> <p> _ finish = false; <br/> // _ Insafe = false; <br/>}< br/> static void prompt (); </P> <p> void initproinfo (); <br/> processinfo (const processinfo & RHs); <br/> processinfo & operator = (const processinfo & RHs); </P> <p> ~ Processinfo () {}< br/> friend ostream & operator <(ostream & out, const processinfo & RHs ); <br/> friend istream & operator> (istream & in, const processinfo & RHs); <br/> friend class banker; </P> <p> PRIVATE: </P> <p> static string _ sourcename [Max]; <br/> static int _ srctype; // number of resource types <br/> static int _ sourcenum [Max]; // number of various resources <br/> static int _ avaliable [Max]; </P> <p> string _ processname; <br/> int _ allocation [Max]; <br/> Int _ Need [Max]; <br/> static bool _ Insafe; // checks whether a security check has been performed, use this flag to determine whether to output work and max <br/> // false have not entered, no work is output, and Max can be output <br/> // true has already entered, output work without outputting max <br/> int _ tmpalloc [Max]; <br/> int _ tmpneed [Max]; <br/> int _ work [Max]; <br/> bool _ finish; <br/>}; </P> <p> // static variable definition <br/> bool processinfo: _ Insafe = false; <br/> string processinfo: _ sourcename [Max] = {"A", "B", "C" };< br/> int processinfo :: _ srctype = 3; <br/> int Process Info: _ sourcenum [Max] = {10, 5, 7}; <br/> int processinfo: _ avaliable [Max] = {-1 }; // The first number-1 is used to identify available resources. avariable is not computed <br/> // static function definition <br/> void processinfo: prompt () <br/>{< br/> int tmplen = processinfo: _ srctype; <br/> int IX; <br/> cout <"Initially" <tmplen <"type of resources ("; <br/> for (IX = 0; ix <tmplen-1; ix ++) <br/>{ <br/> cout <"[Resource Name:" <processinfo: _ sourcename [ix] <", quantity: "<br/> <processinfo: _ sourcenum [ix] <"],"; <Br/>}< br/> cout <"[Resource Name:" <processinfo: _ sourcename [ix] <"Quantity: "<br/> <processinfo: _ sourcenum [ix] <"] "<")"; </P> <p> // If avariable has been computed, the output is <br/> If (processinfo: _ avaliable [0]! =-1) <br/>{< br/> cout <", the available resources are ("; <br/> for (IX = 0; ix <tmplen-1; IX ++) <br/>{< br/> cout <processinfo: _ avaliable [ix] <","; <br/>}< br/> cout <processinfo: _ avaliable [ix] <")"; <br/>}< br/> cout <Endl; </P> <p >}< br/> // overload output operator <br/> ostream & operator <(ostream & out, const processinfo & RHs) <br/>{< br/> out <RHS. _ processname <"/t"; </P> <p> int tmplen = processinfo: _ srctype; <br/> int MAX [Max]; <br /> Int wkalloc [Max]; // work + allocation <br/> ostream_iterator <int> itout (Out ,""); </P> <p> // determine whether to output work or Max by entering the security check. <br/> If (processinfo: _ Insafe) <br/> {<br/> for (int ix = 0; ix <tmplen; ix ++) <br/> {<br/> wkalloc [ix] = RHS. _ work [ix] + RHS. _ allocation [ix]; <br/>}< br/> copy (RHS. _ work, RHS. _ work + tmplen, itout); <br/>}< br/> else <br/>{< br/> for (int ix = 0; ix <tmplen; IX ++) <br/>{< br/> MAX [ix] = RHS. _ allocation [ix] + R HS. _ Need [ix]; <br/>}< br/> copy (Max, Max + tmplen, itout ); <br/>}</P> <p> out <""; <br/> copy (RHS. _ allocation, RHS. _ allocation + tmplen, itout); <br/> out <""; <br/> copy (RHS. _ Need, RHS. _ Need + tmplen, itout); <br/> out <""; <br/> If (processinfo: _ Insafe) <br/>{< br/> copy (wkalloc, wkalloc + tmplen, itout); <br/> out <"/t"; <br/> RHS. _ finish? Out <"true": Out <"false"; <br/>}< br/> return out; <br/>}< br/> // overload input operator <br/> istream & operator> (istream & in, processinfo & RHs) <br/>{< br/> RHS. initproinfo (); <br/> return in; <br/>}< br/> processinfo & processinfo: Operator = (const processinfo & RHs) <br/>{< br/> _ processname = RHS. _ processname; </P> <p> int tmplen = processinfo: _ srctype; <br/> for (int ix = 0; ix <tmplen; ix ++) <br/> {<br/> _ allocation [ix] = r HS. _ allocation [ix]; <br/> _ Need [ix] = RHS. _ Need [ix]; </P> <p> _ tmpalloc [ix] = RHS. _ tmpalloc [ix]; <br/> _ tmpneed [ix] = RHS. _ tmpneed [ix]; <br/> _ work [ix] = RHS. _ work [ix]; <br/>}</P> <p> _ finish = RHS. _ finish; <br/> _ Insafe = RHS. _ Insafe; </P> <p> return * This; <br/>}< br/> processinfo: processinfo (const processinfo & RHs) <br/>{< br/> _ processname = RHS. _ processname; </P> <p> int tmplen = processinfo: _ srctype; <br/> for (int ix = 0; ix <Tmplen; ix ++) <br/>{< br/> _ allocation [ix] = RHS. _ allocation [ix]; <br/> _ Need [ix] = RHS. _ Need [ix]; </P> <p> _ tmpalloc [ix] = RHS. _ tmpalloc [ix]; <br/> _ tmpneed [ix] = RHS. _ tmpneed [ix]; <br/> _ work [ix] = RHS. _ work [ix]; <br/>}</P> <p> _ finish = RHS. _ finish; <br/> // _ Insafe = RHS. _ Insafe; <br/>}< br/> void processinfo: initproinfo () <br/>{< br/> cout <"Enter the process name :"; <br/> CIN >>_processname; <br/> int tmplen = processinfo: _ srctype; <Br/> int IX; <br/> cout <"Enter the allocated [allocation] for each type of resources (separated by spaces ):"; <br/> for (IX = 0; ix <tmplen; ix ++) <br/>{< br/> CIN >>_allocation [ix]; <br/>}< br/> cout <"Enter the requirement for each type of resource [need] (separated by spaces):"; <br/> for (IX = 0; IX <tmplen; ix ++) <br/>{< br/> CIN >>_need [ix]; <br/>}< br/> cout <Endl; <br/>}</P> <p> class banker {<br/> Public: <br/> banker () <br/>{< br/> _ ismodify = false; <br/>}< br/> banker (const banker & RHs) <br/>{< br/> Copy (RHS. _ Val. begin (), RHS. _ Val. end (), _ Val. begin (); <br/>}< br/> void initbanker (); <br/> bool safecheck (); </P> <p> int request (int * request); </P> <p> bool bankercheck (INT rindex, int * request ); </P> <p> friend ostream & operator <(ostream & out, const banker & RHs); <br/> PRIVATE: <br/> // used to reset the finish and work variables <br/> void reset (); <br/> bool calavariable (); <br/> bool modify (); </P> <p> bool _ ismodify; // determines whether the initialization information has been modified. Alse is not modified. True is modified. <br/> vector <processinfo> _ Val; <br/>}; <br/> // Private function define <br/> bool BANKER:: Modify () <br/>{< br/> int tmplen; <br/> cout <"Number of input resource types:"; <br/> CIN> tmplen; <br/> processinfo: _ srctype = tmplen; </P> <p> cout <"Enter various resource names (separated by spaces ):"; <br/> for (int ix = 0; ix <tmplen; ix ++) <br/>{< br/> CIN> processinfo: _ sourcename [ix]; <br/>}< br/> cout <"Enter the number of resources (separated by spaces):"; <br/> for (int ix = 0; I X <tmplen; ix ++) <br/>{< br/> CIN> processinfo: _ sourcenum [ix]; <br/>}< br/> return true; <br/>}< br/> bool BANKER: calavariable () // calculate the number of available resources for each type <br/>{< br/> int srctypenum = processinfo: _ srctype; <br/> int processnum = _ Val. size (); <br/> int usetotal; <br/> for (INT id = 0; id <srctypenum; Id ++) <br/>{< br/> usetotal = 0; <br/> for (int ix = 0; ix <processnum; ix ++) <br/> {<br/> // processinfo: _ avaliable [ID] + = _ Val [ix]. _ Allocation [ID]; <br/> usetotal + = _ Val [ix]. _ allocation [ID]; <br/>}< br/> // processinfo: _ avaliable [ID] = <br/> // processinfo :: _ sourcenum [ID]-processinfo: _ avaliable [ID]; <br/> processinfo: _ avaliable [ID] = processinfo: _ sourcenum [ID]-usetotal; <br/> If (processinfo: _ avaliable [ID] <0) <br/>{< br/> // cout <"the number of available resources is negative "; <br/> return false; <br/>}< br/> return true; <br/>}< br/> void BANKER: reset () <br />{< Br/> int tmplen = processinfo: _ srctype; <br/> int processnum = _ Val. size (); <br/> for (int ix = 0; ix <processnum; ix ++) <br/>{< br/> _ Val [ix]. _ finish = false; <br/> for (INT id = 0; id <tmplen; Id ++) <br/>{< br/> _ Val [ix]. _ work [ID] = 0; <br/>}< br/> // end private function define </P> <p> bool BANKER :: bankercheck (INT rindex, int * request) <br/> {<br/> // enter pre-allocation <br/> // use tmpalloc to save the unmodified allocation <br/> // use TM Pneed save unmodified need <br/> // use the Temporary Variable tmpavaliable to save unmodified avaliable <br/> // modify avaliable, allocation, need <br/> int tmplen = processinfo: _ srctype; <br/> int tmpavaliable [Max]; <br/> int IX; <br/> for (IX = 0; ix <tmplen; ix ++) <br/>{< br/> _ Val [rindex]. _ tmpalloc [ix] = _ Val [rindex]. _ allocation [ix]; <br/> _ Val [rindex]. _ tmpneed [ix] = _ Val [rindex]. _ Need [ix]; <br/> tmpavaliable [ix] = processinfo: _ avaliable [ix]; <br/> processinf O: _ avaliable [ix]-= request [ix]; <br/> _ Val [rindex]. _ allocation [ix] + = request [ix]; <br/> _ Val [rindex]. _ Need [ix]-= request [ix]; <br/>}< br/> // security check has been called at the beginning, therefore, you need to reset finish and Work <br/> Reset (); <br/> // security sequence does not exist. Reset avaliable, allocation, need <br/> If (! Safecheck () <br/>{< br/> for (IX = 0; ix <tmplen; ix ++) <br/>{< br/> _ Val [rindex]. _ allocation [ix] = _ Val [rindex]. _ tmpalloc [ix]; <br/> _ Val [rindex]. _ Need [ix] = _ Val [rindex]. _ tmpneed [ix]; <br/> processinfo: _ avaliable [ix] = tmpavaliable [ix]; <br/>}< br/> return false; <br/>}< br/> return true; <br/>}< br/> void BANKER: initbanker () <br/>{< br/> char C; <br/> processinfo: prompt (); <br/> cout <"whether to modify the default initial phase of a process Off information (y/N): "; <br/> CIN> C; <br/> If (C = 'y' | C = 'y ') <br/>{< br/> _ ismodify = true; <br/> If (! Modify () {<br/> cout <"operator error! "; <Br/> exit (1); <br/>}< br/> If (_ ismodify) <br/>{< br/> processinfo: prompt (); <br/>}< br/> do {<br/> processinfo tmpobj; <br/> CIN> tmpobj; <br/> _ Val. push_back (tmpobj); <br/> // system ("CLS "); // If you think you need to refresh the screen, add <br/> cout <"Whether the input is complete and enter the security check (y/N ):"; <br/> cout. flush (); </P> <p> CIN> C; <br/>}while (C! = 'Y' & C! = 'Y'); </P> <p> If (! Calavariable () <br/>{< br/> cout <"Calculator avariable error, avariable have negative value! "<Endl; <br/> exit (1); <br/>}< br/> bool BANKER: safecheck () <br/>{< br/> int processnum = _ Val. size (); <br/> int tmplen = processinfo: _ srctype; <br/> int tmpwork [Max] = {0 }; </P> <p> copy (processinfo: _ avaliable, processinfo: _ avaliable + tmplen, tmpwork); <br/> bool isnlessw = true; // identify whether need is smaller than work; <br/> int safenum = 0; // number of times that finish is set to true </P> <p> vector <processinfo> safelist; <br/> // use processnum for Large Loop query in the worst case Find <br/> for (INT I = 0; I <processnum; I ++) <br/> {// small and medium cycles in each large loop, loop processnum Times <br/> for (int ix = 0; ix <processnum; ix ++) <br/>{</P> <p> If (_ Val [ix]. _ finish = false) <br/>{< br/> isnlessw = true; <br/> // judge need <= work; <br/> for (INT id = 0; id <tmplen; Id ++) <br/> {<br/> If (_ Val [ix]. _ Need [ID]> tmpwork [ID]) <br/>{< br/> isnlessw = false; <br/> break; <br/>}< br/> If (! Isnlessw) // need! <= Work, the modifications to finish and work are skipped. no matching <br/>{< br/> continue found; <br/>}< br/> else <br/> {<br/> _ Val [ix]. _ finish = true; <br/> safenum + = 1; <br/> // modify Work <br/> copy (tmpwork, tmpwork + tmplen, _ Val [ix]. _ work); <br/> // modify tmpwork <br/> for (INT id = 0; id <tmplen; Id ++) <br/> {<br/> // work = work + allocation <br/> tmpwork [ID] = tmpwork [ID] + _ Val [ix]. _ allocation [ID]; <br/>}< br/> // Insert the conforming process item into the security sequence. <br/> safelist. push_back (_ Val [IX]); <br/>}</P> <p> If (safenum! = Processnum) <br/>{< br/> cout <"security sequence does not exist" <Endl; <br/> return false; <br/>}< br/> else <br/> {<br/> processinfo: _ Insafe = true; // modify the Insafe flag, indicating that the security check is performed. <br/> // this parameter is used to output work at output without outputting Max. <br/> cout <"A security sequence exists! "<Endl; <br/> // processinfo: prompt (); <br/> cout <"process/twork/tallocation/TNeed/twork + allocation/tfinish/N"; <br/> ostream_iterator <processinfo> itout (cout, "/N"); <br/> copy (safelist. begin (), safelist. end (), itout); <br/>}< br/> return true; <br/>}< br/> int BANKER: Request (int * request) <br/>{< br/> int tmplen = processinfo: _ srctype; <br/> // int request [Max]; <br/> cout <"Enter the process name of the requested resource ("; <br/> int processn Um = _ Val. size (); <br/> int IX; // used for the subscript index variable in the loop <br/> int rindex =-1; // used to save the index value of the process corresponding to the request in the process sequence <br/> for (IX = 0; ix <processnum-1; ix ++) <br/> {<br/> cout <_ Val [ix]. _ processname <","; <br/>}< br/> cout <_ Val [processnum-1]. _ processname <"):"; <br/> string rprocessname; <br/> CIN> rprocessname; <br/> bool isnametrue = false; // identify whether the entered process name is correct. <br/> // int isnametrue = 0; // identifies whether the entered process name is correct. <br/> // determine whether the process name is in the process sequence. <Br/> for (IX = 0; ix <processnum; ix ++) <br/>{< br/> If (rprocessname. compare (_ Val [ix]. _ processname) = 0) <br/>{< br/> isnametrue = true; <br/> // isnametrue = 1; <br/> rindex = IX; <br/> break; <br/>}< br/> If (! Isnametrue) <br/>{< br/> cout <"the input process name is not in the process sequence. An error occurred while exiting! "<Endl; <br/> exit (1 ); <br/>}</P> <p> cout <"Enter the number of requests to various types of resources (separated by spaces ):"; <br/> for (IX = 0; ix <tmplen; ix ++) <br/>{< br/> CIN> request [ix]; <br/>}</P> <p> bool isrlessn = true; // identifies whether the request is smaller than need; <br/> // request <= need <br/> for (IX = 0; ix <tmplen; ix ++) <br/>{< br/> If (request [ix]> _ Val [rindex]. _ Need [ix]) <br/>{< br/> isrlessn = false; <br/> break; <br/>}< br/> If (! Isrlessn) <br/>{< br/> cout <"error: request! <= Need "<Endl; <br/> return-1; <br/>}</P> <p> bool isrlessa = true; // identifies whether the request is smaller than avaliable; <br/> // request <= avaliable <br/> for (IX = 0; ix <tmplen; ix ++) <br/>{< br/> If (request [ix]> processinfo: _ avaliable [ix]) <br/>{< br/> isrlessa = false; <br/> break; <br/>}< br/> If (! Isrlessa) <br/>{< br/> cout <"error: request! <= Avaliable "<Endl; <br/> return-1; <br/>}< br/> return rindex; <br/>}< br/> ostream & operator <(ostream & out, const banker & RHs) <br/>{< br/> cout <Endl; <br/> processinfo: prompt (); <br/> cout <"process/Tmax/tallocation/TNeed/N "; <br/> ostream_iterator <processinfo> itout (Out, "/N"); <br/> copy (RHS. _ Val. begin (), RHS. _ Val. end (), itout); <br/> return out; <br/>}< br/> int main () <br/>{< br/> banker B; <br/> B. Initbanker (); </P> <p> cout <B; <br/> If (! B. safecheck () <br/>{< br/> cout <"there is no security sequence at t0 moment, end and exit" <Endl; <br/> exit (1 ); <br/>}< br/> else <br/>{< br/> cout <"so a secure sequence exists at t0" <Endl; <br/>}</P> <p> int request [Max]; <br/> int rindex; <br/> while (1) <br/>{< br/> rindex = B. request (request); <br/> If (rindex =-1) <br/>{< br/> cout <"the request does not meet the condition" <Endl; <br/> continue; <br/>}< br/> If (! B. bankercheck (rindex, request) <br/>{< br/> cout <"bankercheck error: No exist safe queue! "<Endl; <br/>}< br/> return 0; <br/>}
The running result is as follows:
Three types of resources ([Resource Name: A, quantity: 10], [Resource Name: B, quantity: 5], and [Resource Name: C quantity: 7]) <br/> whether to modify the default initial information of a process (y/N): n <br/> enter the process name: p0 <br/> input [allocation] (separated by spaces) allocated to each type of resource ): 0 1 0 <br/> enter the requirement for each type of resource [need] (separated by spaces): 7 4 3 <br/> whether the input is complete, enter the security check (y/N): n <br/> enter the process name: P1 <br/> enter the allocated [allocation] (separated by spaces) for each type of resources ): 2 0 0 <br/> enter the requirement for each type of resource [need] (separated by spaces): 1 2 2 <br/> whether the input is complete, enter the security check (y/N): n <br/> enter the process name: P2 <br/> enter the allocated [allocation] (separated by spaces) for each type of resources ): 3 0 2 <br/> enter the requirement for each type of resource [need] (empty Grid separated): 6 0 0 <br/> whether the input is complete, and enter the security check (y/N): n <br/> enter the process name: p3 <br/> enter the allocated [allocation] for each type of resources (separated by spaces ): 2 1 1 <br/> input requirements for each type of resource [need] (separated by spaces): 0 1 1 <br/> whether the input is complete, enter the security check (y/N): n <br/> enter the process name: P4 <br/> enter the allocated [allocation] (separated by spaces) for each type of resources ): 0 0 2 <br/> enter the requirement for each type of resource [need] (separated by spaces): 4 3 1 <br/> whether the input is complete, and enter the security check (y/N): y <br/> initially there are three types of resources ([Resource Name: A, quantity: 10], [Resource Name: B, quantity: 5], [Resource Name: C quantity: 7]), can <br/> use resources are (, 2) <br/> process Max allocation need <br/> P0 7 5 3 0 1 0 7 4 3 <br/> P1 3 2 2 2 0 0 1 2 2 2 <br/> P2 9 0 2 3 0 2 6 0 0 <br/> P3 2 2 2 2 2 1 1 0 1 1 <br/> P4 4 3 3 0 0 2 4 3 1 <br/> Security sequence exists! <Br/> process work allocation need work + allocation finish <br/> P1 3 3 2 2 0 0 1 2 5 3 2 true <br/> P3 5 3 2 2 1 1 0 1 1 7 4 3 true <br/> P4 7 4 3 0 0 2 4 3 1 7 4 5 true <br/> P0 7 4 5 0 1 0 7 4 3 7 5 5 true <br/> P2 7 5 5 3 0 2 6 0 0 10 5 7 true <br/> therefore, a secure sequence exists at t0 moment <br/> enter the requested resource process name (P0, p1, P2, P3, P4): P1 <br/> enter the number of requests for various types of resources (separated by spaces): 1 0 2 <br/> there is a security sequence! <Br/> process work allocation need work + allocation finish <br/> P1 2 3 0 3 0 2 0 2 0 5 3 2 true <br/> P3 5 3 2 2 1 1 0 1 1 7 4 3 true <br/> P4 7 4 3 0 0 2 4 3 1 7 4 5 true <br/> P0 7 4 5 0 1 0 7 4 3 7 5 5 true <br/> P2 7 5 5 3 0 2 6 0 0 10 5 7 true <br/> enter the process name of the requested resource (P0, p1, P2, P3, P4): P4 <br/> enter the number of requests for various types of resources (separated by spaces): 3 3 0 <br/> error: request! <= Avaliable <br/> the request does not meet the conditions. <br/> enter the process name (P0, P1, P2, P3, P4) of the requested resource ): p0 <br/> enter the number of requests to various types of resources (separated by spaces): 0 2 0 <br/> no security sequence <br/> bankercheck error: No exist safe queue! <Br/> enter the process name (P0, P1, P2, P3, P4) of the requested resource: P0 <br/> enter the number of requests for various resources (separated by spaces ): 0 1 0 <br/> A security sequence exists! <Br/> process work allocation need work + allocation finish <br/> P1 2 2 0 3 0 2 0 2 0 5 2 2 true <br/> P3 5 2 2 2 1 1 0 1 1 7 3 3 true <br/> P4 7 3 3 0 0 2 4 3 1 7 3 5 true <br/> P0 7 3 5 0 2 0 7 3 3 7 5 5 true <br/> P2 7 5 5 3 0 2 6 0 0 10 5 7 true <br/> enter the process name of the requested resource (P0, p1, P2, P3, P4): 22 <br/> the input process name is not in the process sequence. An error occurred while exiting! <Br/> press any key to continue...