mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-08 15:52:26 +01:00
Author:halw
Date:2011-02-08T22:13:37.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@754 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
[[Property:title|Dining philosophers]]
|
||||
[[Property:weight|-12]]
|
||||
[[Property:uuid|569f012e-7913-fbdf-7ad7-cd17d82e64aa]]
|
||||
{{UnderConstruction}}
|
||||
|
||||
|
||||
{{Beta}}
|
||||
|
||||
@@ -12,14 +10,48 @@
|
||||
|
||||
In the [http://en.wikipedia.org/wiki/Dining_philosophers_problem dining philosopers] a number of philosophers (five, in our example) are seated at a round table. On the table are five plates of food, one in front of each philosopher, and five forks, one between each adjacent pair of plates. So each philosopher has a plate in front of him and a fork to his left and a fork to his right.
|
||||
|
||||
The philosophers spend all their time in either of only two states: they are thinking or they are eating. The philosophers may be brilliant thinkers, but apparently manual dexterity is not their strong suit. This is evidenced by the fact that while eating, any philosopher must pick up both of the forks positioned next to his plate. So, while eating he must have possession of both forks, and while thinking, he has put down any forks that he had previously used. Therefore, any particular philosopher has the opportunity to eat only when the two philosophers on either side of him are thinking and have made their forks available.
|
||||
The philosophers spend all their time in either of only two states: they are thinking or they are eating. The philosophers may be brilliant thinkers, but apparently manual dexterity is not their strong suit. This is evidenced by the fact that in order to eat, any philosopher must be able to pick up both of the forks positioned next to his plate (which he can do, so long as the philosopher next to him has not already done so). So, while eating he must have possession of both forks, and while thinking, he has put down any forks that he had previously used. Therefore, any particular philosopher has the opportunity to eat only when the two philosophers on either side of him are thinking and have made their forks available.
|
||||
|
||||
Apart from any negative consequences of these questionable sanitary practices, the dining philosophers can, in improperly designed solutions, encounter problems related to concurrency. For example, if all philosophers were to pick up the fork to their right and then wait for the fork to their left to become available (or vice versa), they would achieve a ''deadlock''. A ''starvation'' situation might occur if, because of unfairness in the solution algorithm, one or more philosophers get stuck in thinking mode because they can never secure the two forks necessary to eat.
|
||||
Apart from any negative consequences from these questionable sanitary practices, the dining philosophers can, in improperly designed solutions, encounter problems related to concurrency. For example, if all philosophers were to pick up the fork to their right and then wait for the fork to their left to become available (or vice versa), they would achieve a ''deadlock''. A ''starvation'' situation might occur if, because of unfairness in the solution algorithm, one or more philosophers get stuck in thinking mode because they can never secure the two forks necessary to eat.
|
||||
|
||||
|
||||
=Highlights=
|
||||
|
||||
|
||||
This example includes three classes relevant to the problem: <code>APPLICATION</code>, <code>PHILOSOPHER</code>, and <code>FORK</code>. Class <code>APPLICATION</code> sets the problem in motion by creating the forks and philosophers all typed as <code>separate</code>, and then applying the feature <code>live</code> to each philosopher after creation.
|
||||
|
||||
Class <code>PHILOSOPHER</code> models the philosophers. The totality of a philosopher's exciting activities is modeled by the feature <code>step</code>:
|
||||
|
||||
<code>
|
||||
step
|
||||
-- Perform a philosopher's tasks.
|
||||
do
|
||||
think
|
||||
eat (left_fork, right_fork)
|
||||
end
|
||||
</code>
|
||||
|
||||
This feature is called by <code>{PHILOSOPHER}.live</code> repeatedly until the philosopher has eaten a prescribed number of times.
|
||||
|
||||
The feature <code>think</code> requires no access to shared objects, but the feature <code>eat</code> depends upon the philosopher's ability to secure access to both of the forks adjacent to his plate. Because all forks are separate objects, each call to <code>eat</code> waits until the processors for both the left and right forks are available (in accordance with the Wait rule).
|
||||
|
||||
Another interesting feature of this example is the feature <code>{PHILOSOPHER}.eat</code>. If you look at the text of this feature
|
||||
|
||||
<code>
|
||||
eat (l, r: separate FORK)
|
||||
-- Eat, having grabbed l and r.
|
||||
do
|
||||
io.put_string ("Philosopher " + id.out + ": taking forks%N")
|
||||
times_eaten := times_eaten + 1
|
||||
io.put_string ("Philosopher " + id.out + ": eating%N")
|
||||
io.put_string ("Philosopher " + id.out + ": putting forks back%N")
|
||||
end
|
||||
</code>
|
||||
|
||||
and you're not wearing your SCOOP glasses, this could look a little odd to you. Here is a routine that takes two arguments <code>l</code> and <code>r</code> representing the left and right forks. But then, <code>l</code> and <code>r</code> are never used in body of the routine!
|
||||
|
||||
However, with SCOOP in mind, we realize that the fork objects are shared resources to which exclusive access must be secured before a philosopher can eat. In this example, the fork object themselves don't really do anything except serve that purpose. (Take a look at the FORK class, and you'll see that it has no features.)
|
||||
|
||||
In other concurrency problems, it is likely that shared resources would play a more active role than the forks of the dining philosophers, but here it's just not necessary.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user