main() {
pel Producer() p;
pel Consumer(p);
}
(mel item val) Producer () {
while ( !timeToPunchOut() )
?val = produce();
}
void Consumer (Producer p) {
try {
while ( 1 )
consume(?p!val);
}
catch (p!NOMORE){
printf ("Producer has done producing. I go home too");
}
}
Here, the Consumer keeps consuming until its wait for the mel
Now, let us look at the reverse problem, where the Consumer terminates before consuming all the produced items. The Producer keeps producing and deposits into its mel variable
There is a corresponding
val
of the pel p
fails due to the NOMORE
pel exception. This exception is raised by the Producer p
as it terminates (normally or abnormally). This allows the Consumer to clean itself up (here by printing a message) and terminate too. When both Producer and Consumer have terminated, the whole program terminates.Now, let us look at the reverse problem, where the Consumer terminates before consuming all the produced items. The Producer keeps producing and deposits into its mel variable
val
, which acts like a buffer between the Producer and Consumer. If the mel val
is full and cannot accept any more items, the Producer then waits at the ?
for the Consumer to clear the mel val
. If the Consumer has terminated (normally or abnormally), the Producer will wait forever. To break out of such potentially infinite wait, the Producer can check for the NOOUT
mel exception:
(mel item val) Producer () {
try {
while ( !timeToPunchOut() )
?val = produce();
}
catch (val!NOOUT) {
printf ("Consumer has done consuming. I go home too");
}
}
The NOOUT
mel exception is raised when there is no reader subscribing to the mel and the mel buffer stays full for some time (this "some time" is configurable).There is a corresponding
NOIN
mel exception for the Consumer to check in case there are no Producer subscribing to the mel to deposit new values. Let's rewrite the example so that we now have one Consumer but two Producers:
main() {
mel int Val;
pel Producer1();
pel Producer2();
pel Consumer();
}
void Producer1 () {
for (int i=0; i<10; ++i)
?Val = produce();
}
void Producer2 () {
for (int i=0; i<70; ++i)
?Val = produce();
}
void Consumer () {
try {
while ( 1 )
consume (?Val);
}
catch (Val!NOIN) {
printf ("No more producers");
}
}
The mel Val
is now used by both Producers and the single Consumer. Producer1
produces 10 times then terminates. Producer2
does 70 times and terminates. After both of them have terminated, the Consumer will wait forever at the ?Val
.
Here the Consumer protects itself from a forever wait by checking the NOIN
mel exception. This exception is raised by the run-time
environment when it detects that there are no pel processes that register to produce for the mel variable Val
for some time (this "some time" is configurable).
No comments:
Post a Comment