Welcome
» NERWous C
A Serial Producer / Consumer
This is a Producer / Consumer example written in standard C language:
A 3-Task NERW Producer / Consumer
Let's apply the NERW model to make the above code concurrent:
The
The
With all tasks it forks terminated, the
A 2-Task NERW Producer / Consumer
Instead of pelling a task to run
A Serial Producer / Consumer
This is a Producer / Consumer example written in standard C language:
main () {
int c;
while (c = Produce())
Consume(c);
}
The main
task works serially. It calls Produce
to get a value to c
, then calls Consume
to consume it. The cycle repeats until there is no more products (with Produce
returning 0).
A 3-Task NERW Producer / Consumer
Let's apply the NERW model to make the above code concurrent:
main () {
<mel> int store;
<pel> Producer (store);
<pel> Consumer (store);
}
void Producer (<mel> int store) {
int c;
while ( c = Produce() )
<?>store = c;
<?>store = 0;
}
void Consumer (<mel> int store) {
int c;
while ( c = <?>store )
Consume(c);
}
The task main
creates a mel
variable, store
, as the communication channel between the Producer and Consumer. It then creates a task to run the Producer
code via the pel
construct, and immediately creates another task to run the Consumer
code. The task main
then waits for all the tasks it forks to be terminated.
The
Producer
task keeps producing until Produce
returns 0. Every time it has a product, it will see if the mel store
is available for it to deposit the product. By definition, the mel variable has one slot (we will see how to define a multi-slotted mel variable later). If a slower Consumer
task has not consumed the previous product, the Producer
will wait at the mel via the <?> construct. Once the deposit to the mel is successful, the Producer
resumes its Produce
chore. When it cannot Produce
any more, it will deposit a 0 value to the mel to alert the Consumer
task. The Producer
task then terminates.
The
Consumer
task runs in parallel with the Producer
task. The two synchronize at the mel variable store
. If store
is empty (due to a slower Producer
) or is locked by the Producer
while it deposits a new product, the Consumer
task will wait at the <?> construct. Once it sees a 0-valued product, the Consumer
task terminates.
With all tasks it forks terminated, the
main
task terminates itself. The application then exits.
A 2-Task NERW Producer / Consumer
Instead of pelling a task to run
Consumer
, the task main
can run it by itself:
main () {
<mel> int store;
<pel> Producer (store);
Consumer (store);
}
This will save some task resources.
No comments:
Post a Comment