mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-07 15:22:31 +01:00
Updated to correspond to updated example (build 85949).
Author:halw Date:2011-03-25T18:07:42.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@858 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -7,21 +7,19 @@
|
||||
|
||||
=Description=
|
||||
|
||||
The single-element producer-consumer is a variant of the classic [http://en.wikipedia.org/wiki/Producer-consumer_problem producer-consumer] problem. A producer produces products, in this case integers, which are consumed by a consumer. The producer and consumer are managed by separate [[Concurrent Eiffel with SCOOP#Processors|processors]], so any access they have to one another must be synchronized through scoop mechanisms.
|
||||
The single-element producer-consumer is a simpler variant of the classic [http://en.wikipedia.org/wiki/Producer-consumer_problem producer-consumer] problem. A producer produces products, in this case integers, into a single-element inventory. The products are then consumed from inventory by a consumer. The producer, consumer, and inventory are managed by separate [[Concurrent Eiffel with SCOOP#Processors|processors]], so any access they have to one another must be synchronized through scoop mechanisms.
|
||||
|
||||
=Highlights=
|
||||
|
||||
In the single-element producer-consumer only a single producer and single consumer are created, and there is only storage allowing for a single instance of the product. So, effectively in this example, the bounded buffer of the classic producer-consumer problem has a size of one and is not a shared resource. Rather, the single product element (in this case, an integer) is held by the producer and provided to the consumer upon request.
|
||||
In the single-element producer-consumer only a single producer and single consumer are created, and there is only storage allowing for a single instance of the product. So, effectively in this example, the bounded buffer of the classic producer-consumer problem has a size of one.
|
||||
|
||||
The <code>PRODUCER</code> class interface exposes features <code>make_something</code> in which a product is produced and <code>get_something: INTEGER</code> which allows a consumer to retrieve the latest product, if one is available. Feature <code>has_something: BOOLEAN</code> is the indicator of whether an integer has been produced and is available for consumption.
|
||||
The classes modeling the different actors have obvious names: <code>PRODUCER</code>, <code>CONSUMER</code>, and <code>INVENTORY</code>. The root class of the example creates one <code>separate</code> instance of each of these, and then brings the producer and consumer to life.
|
||||
|
||||
The <code>CONSUMER</code> class has a feature <code>take</code> that consumes a product from the producer (by calling <code>{PRODUCER}.get_something</code>), if a product exists. The precondition for <code>take</code> is based on <code>{PRODUCER}.has_something</code>. This is an [[Concurrent Eiffel with SCOOP#Design by Contract and SCOOP|uncontrolled precondition]], so instances of <code>CONSUMER</code> are not obliged to ensure that it holds before calling <code>take</code>. Rather, under SCOOP, this precondition will ensure that the application of <code>take</code> waits until the producer does have a product available for consumption.
|
||||
The <code>PRODUCER</code> class supports a procedure <code>produce</code> in which a product is produced and stored in the single-element <code>INVENTORY</code>. The producer can only produce an element if the inventory is currently empty. Class <code>INVENTORY</code> exports a boolean query <code>has_item</code> which is the indicator of whether a product has been produced and is available for consumption. So <code>{PRODUCER}.produce</code> has a precondition that depends upon <code>{INVENTORY}.has_item</code> being false. Because the inventory is handled by a separate processor, this precondition is [[Concurrent Eiffel with SCOOP#Preconditions|uncontrolled]] and will cause the producer to wait until the condition is true to proceed.
|
||||
|
||||
Likewise, there is an uncontrolled precondition on <code>{PRODUCER}.make_something</code> that allows the feature to be applied only when <code>has_something</code> does not hold.
|
||||
The <code>CONSUMER</code> class works in a way that is largely the symmetrical opposite of <code>PRODUCER</code>. The consumer tries to <code>consume</code> the item from the <code>INVENTORY</code>. But this only possible if an item has been produced and is available. So <code>{CONSUMER}.consume</code> has a "wait" precondition based on the query <code>{INVENTORY}.has_item</code>.
|
||||
|
||||
So the heart of the problem is the synchronization between producer and consumer. If there's already a product in storage, the producer cannot produce more and must wait. Only when the consumer consumes the current product can the producer produce again. On the other side, if there's a product currently in storage with the producer, then the consumer can consume that product. Otherwise, the consumer must wait until the producer produces a new product.
|
||||
|
||||
The example's root class <code>APPLICATION</code> declares a <code>PRODUCER</code> and a <code>CONSUMER</code>, both <code>separate</code>. <code>APPLICATION</code> starts the example running by creating the producer and consumer, then by looping calls to the <code>{PRODUCER}.make_something</code> requesting it constantly to produce products.
|
||||
So the heart of the problem is the synchronization between producer and consumer sharing a single inventory. If there's already a product in inventory, the producer cannot produce more and must wait. Only when the consumer consumes the current product can the producer produce again. For the consumer's part, if there's a product currently in inventory, then the consumer can consume that product. Otherwise, the consumer must wait until the producer produces a new product. The synchronization is handled by the SCOOP mechanism of wait preconditions on the inventory.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user