⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 project1.html

📁 利用银行家算法避免死锁。掌握银行家算法中的数据结构
💻 HTML
字号:
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <TITLE>OSF Project 1:  The Banker's Algorithm</TITLE>
</HEAD>

<BODY background="../../text2.jpg">
<h2>
<CENTER>OSF Project 1:</center>
<center>The Banker's Algorithm</CENTER>
</h2>

<H3>General</H3>

<p> This first project has the following characteristics compared to the remaining three:

<ul>
	<li> It involves the least amount of actual coding.  All you have
		to do is implement <i>one method</i> in <i>one C++ source
		file</i>.  Everything else is provided.
		If you use over 100 lines of code for your implementation, 
		you probably worked too hard.
	<li> It may involve the biggest learning curve if you're
		not yet comfortable with a C++ development environment.
		I've kept the size small for this reason.
	<li> It's end result (a "Banker" class) will be reused as-is in Projects
		3 and 4.
</ul>

Everything you need to know is on and around pages 222 and 223 of your Silberschatz book.
But let me provide a little practical background terminology, courtesy of 
<a href="http://www.rh.edu/~davec">Dave Clarke</a>...

<H3>Terminology:  Deadlock</H3>
Consider the following resolution made in the last century by a town council:

<OL>	<LI>Resolved, that this town shall build a new jail.
	<LI>Resolved, that the new jail shall be built from material from the old jail.
	<LI>Resolved also, that the old jail shall be used until the new jail is finished.
</OL>

Bummer!  Each jail requires the same resource (material) at the same time.
It's the classic "Catch 22" scenario.  

<p>In operating systems terminology, we'd say the the over-committment of resources
will lead to Deadlock, because, as soon as some of the material is taken away from the
old jail, neither jail will function correctly.


<p> Deadlock is always a possibility when a resource is shared by more than one process. 
One of the approaches that may be taken to combat this problem is known as 
<i>deadlock avoidance</i>. The major player in this technique is the 
<i>Banker's Algorithm</i>. You will be creating your own version
of this algorithm in C++.



<H3>Downloads</H3>

There are three source files required to do this project:

<ul>
	<li>  Banker.h
	<li>  Banker.cpp
	<li>  Project.cpp

</ul>

Subsequent projects will have many more files.  So you may want to get in the habit
of downloading everything required via <a href="project1.zip"> zip file</a>.

<h3>
<b><font color="green">Banker</font></b>
</h3>
<p><a href="Banker.h">Banker.h</a>
<br><a href="Banker.cpp">Banker.cpp</a>
<p>
The Banker header file has the following interesting features:

<ul>
<li>	Inclusion of &lt map &gt, which is the Standard Template Library map template.
		This allows us to map Process ID numbers (integral PIDs) to the current
		state of resources associated with them.

<li>	Definition of four important types of exceptions that you'll need to
		throw if unsafe conditions arise.  These are:
	<ul>
	<li>  BankerUnsafePidException.  A request has been made for a 
				PID that doesn't exist,
	<li>  BankerUnsafeContractException.  A valid PID 
				has made a request that overdraws on the 
				maximum resources for which it contracted.
	<li>  BankerUnsafeTotalException.  An otherwise-OK
				request can't be granted right now because there
				aren't enough system resources.
	<li>  BankerUnsafeCommittedException.  An otherwise-OK
				request can't be granted.  Even though the 
				system resources are currently available, they
				are committed.  Release of the resources right now
				could lead to deadlock depending on the order in
				which other PIDs make subsequent requests.

	</ul>
<li>	The definition of a structure called Resources, which is just a handy
		way of grouping three integers.  We will use these integers to count
		resources.  In our case, we'll play with:  Files on a file system, 
		Pages of main memory, and Mutices (semaphores).  As far as what you're
		required to implement is concerned, these "resources" might as well
		be "apples, oranges, and bananas."  The Banker's algorithm could be
		applied to any arbitrary set of resources.

<li>	typdef for ResourcesMap.  This is where we actually start using STL
		in order to map Processes to the resources associated with them.

<li>	Banker class definition.
	<ul>
	<li>  Instance Variables.  (For our purposes, there will never
				be more than one instance of Banker).
		<ul>
		<li> RMax remembers how many Files, Pages,
						and Mutices are in the system.  This
						is assigned during construction of 
						Banker instance, and is immutable.
						(i.e., the Max values never change
						after they're initially assigned.)
		<li> RInUse keeps track of how many Files,
						Pages, and Mutices are currently in 
						use by all processes.  This must
						be less than or equal to RMax.
		<li> RMapMax is an instance of ResourcesMap.
						This is where we use STL to remember
						the maximum values of Files, Pages,
						and Mutices required by each PID.
						Values are assigned during openAccount()
						method and are thereafter immutable.
						So for your purposes (since you're only
						writing isSafe), the values in this map
						are constants.

		<li> RMapInUse is another instance of a ResourcesMap.
						We use this other map to remember, for
						each PID, what the current allocation of
						resources is.  For example, the request()
						method, which is fully implemented for
						you in Banker.cpp, manipulates this 
						map after it calls your isSafe() implementation.

		</ul>
	<li>	Instance Methods.  The only method you're required to implement is 
		the private method isSafe().  Its whole purpose is
		to throw one of the four types of exceptions listed above.  HINT:
		The order listed above is a good order in which to test for 
		unsafe conditions.  In other words, your code should be 
		structured as follows:

		<ul>
		<li>BankerUnsafePidException.  First test
							to see if the caller sent in a
							valid PID.  You might want to 
							plagiarize from closeAccount().
		<li>BankerUnsafeContractException.  Test
							whether iFiles, iPage, iMutex
							passed in to isSafe exceeds the
							contracted value in RMapMax
							for that PID.  You might want
							to look at code in openAccount(),
							which is where RMapMax[iPid] was
							set in the first place.  That
							should make you comfortable with
							how to reference data stored in STL.

		<li>BankerUnsafeTotalException.  The idea
							here is pretty simple.  If we
							add iFiles, iPages, and iMutex
							to the values in RMapInUse, we 
							may exceed the values in RMapMax.
							That would be unsafe.

		<li>BankerUnsafeComittedException.  This
							is the hard part.  You'll probably
							have to read pp. 222-23 about 10
							times before you start to feel
							comfortable with what to do here.
							We'll talk about in class every
							week until the project's due.
		</ul>
	</ul>
</ul>

<h3>
<b><font color="green">Project1</font></b>
</h3>
<p><a href="Project1.cpp">Project1.cpp</a>
<p>

You should not have to make any changes to the Project.cpp file.  It has the
following features:

<ul>
<li> Global Variables.  There are two global variables call osfLog1 and osfLog2.
	They are only used in order to generate comments to a txt file on your system,
	useful for debugging.  They have nothing to do with the actual operation of the project
	(and that's the only reason I would ever allow global variables anywhere...).  You
	will be required to turn in the output of osfLog1.  osfLog2 can be used by you
	however you wish.

<li> tryRequest() method.  This method provides for the bulk of testing that will
	be done on your Banker's Algorithm.  It consists of a try/catch block
	which makes a request() of the Banker, catches exceptions that you throw
	in isSafe(), and prints out results.  The tryRequest() method is invoked 
	by main().

<li> tryMemoryTest().  This method has nothing to do with the Banker per se.  It's 
	an add-on method I provided in order to promote discussion in class about
	how memory is managed, particularly with C++ programs.  This method
	is invoked by main().
	Assuming tryMemoryTest()
	is invoked with all "true" values, three Banker methods will be invoked, each 
	of which involves progressively more memory:
	<ul>
	<li> helloWorld().  This method simply prints a string.  The important feature
		of this method is that it doesn't reference any internal instance 
		variables of Banker.  
	<li> showLimits().  This method prints information stored in the Banker's 
		instance variables.
	<li> request().  This method requires not only instance variables, but
		pointers to STL structures that are instantiated during construction
		of Banker.  The point here is that if the Banker hasn't been 
		properly constructed, the memory may be corrupt.
	</ul>

<li> main().  This method does the following:
	<ul>
	<li> Initializes osfLog1 and osfLog2.
	<li>	Constructs a new instance of Banker, and points to the instance with
		the variable pBanker (pointer to Banker).
	<li>	Calls openAccount() for PIDs 0, 1, 2, 3, and 4.  These PIDs contract
		with the banker for the maximum resources as listed in the 
		Silberschatz example on p. 222.
	<li>	Calls tryRequest() for the sequence specified in the Silberschatz 
		example.
	<li>	Calls tryRequest() three more times to force Banker to throw all
		types of exceptions.
	<li>    Does some memory testing.  This is something I added to promote
		discussion in class about the types of protections offered by
		an operating system to a C++ program.  There are four "memory tests"
		as follows:
		<ul>
		<li> TEST 0.  All methods are invoked (three "trues"), because we're invoking the
			test routine with a valid Banker instance which has
			been properly constructed.
		<li> TEST 1.  We've deleted pBanker, so all bets are off
			about what happens here.  But odds are that the
			memory for pBanker is still around, and our process
			still owns the memory.  Our pBanker variable still
			points to the correct place even though we've 
			relinquished the memory via delete.  The only thing
			that causes my program to crash is the last test,
			which invokes STL data structures allocated
			within pBanker.  So the last flag is set to "false."
			In my testing on Windows '95, some of the information
			in showLimits() is still correct, and other information
			is already corrupted, probably due to reassignment
			of the memory for other purposes.
		<li> TEST 2.  Now I'm really messing with the system.  I point
			pBanker to an arbitrary, uninitialized chunk of 
			memory that happens to be the size of pBanker.
			Then I invoke the same tests as TEST 1.  The difference
			now is that all traces are gone of what used to be correct
			values for instance variables.
		<li> TEST 3.  This time I don't even grab a chunk of memory I own.
			I arbitrarily point pBanker to a very high number, which
			undoubtedly doesn't belong to my process.  This time
			all tests which access any instance variables will cause
			my program to crash (so the last two tests have to be
			skipped using "false").  Note, however, that I can
			still call helloWorld(), because it doesn't involve
			any use of Banker instance memory.

		</ul>
		The lessons you should take from these memory tests are as follows:
		<ul>
		<li>  Memory is a very fragile thing.  Even a robust language 
			like C++ does not relieve the programmer of the need 
			for vigilance about constructors, destructors, new,
			and delete.
		<li>  No environment will give consistent results.  You may be
			able to change some of my falses to trues and still
			run the program without a crash; conversely, you may have
			to change some of the trues to falses to make the program
			run without crashing.
		<li>  Memory problems might go unnoticed because a program
			"gets lucky."  Consider TEST 1, when some of the 
			correct data remained around for a while even after calling
			delete.  So we can't 
			even count on a good test procedure to ensure that
			our code is free of memory leaks.  Often we need to
			buy analysis tools like Purify.
		<li>  Sidenote / soapbox.  This is why many programmers 
			(and managers who know what they are doing) like Java.  
			Java would spit you 
			out the first time you tried to execute TEST 1, thereby
			saving the software industry millions of dollars per day,
			and achieving much better customer satisfaction.
		</ul>
	</ul>
</ul>



<h3>What to Hand In</h3>

Hardcopies only, please.
<ol> 
<li> Complete source code for Banker.cpp, as modified by you to include isSafe() implementation.
<li> A statement about whether your machine / environment was consistent with mine with
	respect to true/false values on memory tests.  Specifically, tell me:
	<ul>
	<li>  Is your environment less forgiving than mine?  I.e., do my values
		for true/false cause the program to crash in your environment?
	<li>  Are you able to get away with setting any of the "falses" to "trues"?
		Which ones?
	<li>  When you do set too many values to "true," what type of failure do you
		see?  Does the system say "Abort," "SEGV," or what?
	<li>  Comment on my implementation of the desctructor for Banker.  Is it OK?
		If not, what should it look like?  Why?
	</ul>
<li> The standard output of your program with a properly implemented isSafe() method,
	and with as many possible "trues" set in Project1.cpp.
<li> The contents of "bankerDebug1.txt".
<li> A statement about whether you were required, in your environment, to make any changes
	to Banker.h, Banker.cpp, or Project.cpp in order to make the program work 
	in your environment.
</ol>


<A HREF="http://www.rh.edu/users/courses.html">Return</a>
 to Rensselaer at Hartford Faculty Course Materials Home Page</A>
</BODY>
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -