Suggestion for Condition variables
Graham St Jack
grahams at acres.com.au
Sun Feb 26 21:39:20 PST 2006
Here is a suggestion for an extension to D to handle pthread-like
condition variables in a way that fits neatly with the "synchronized"
keyword.
I use threads a lot, and quite often find that I need conditions, but
even though all the functionality is there in the locks library, it is
galling that I can't use the same mutex as the "synchronized" keyword.
The alternatives seem to be to:
* Eliminate or ignore the synchronized keyword and use a library all the
time.
* Make the language "aware" of the library, and provide a way of getting
an object's mutex.
* Add some more keywords to handle conditions directly.
My suggestion is for the last, because I like synchronized, and because
I don't like making the language aware of the libraries.
So, the suggestion is to add:
* A "condition" keyword that behaves for the most part just like a bool
data type, but is actually a condition variable.
* A "waitfor" keyword. It would be used like:
waitfor (condition_name);
to wait for the condition to become true, and
waitfor (condition_name; timeout_value);
to wait for the condition to come true, or the timeout period to
expire. Timeout could be ulong nanoseconds, for instance.
Here is a simple example with two conditions in a class in
fast-and-loose pseudo-code. The two conditions are used to show how
simple this arrangement can be compared to trying the same thing in
Java, which has a limit of one condition per object.
The example Queue class is used to facilitate the transfer of data
between two threads - a supplier and a worker. The supplier calls
finalize() when it wants the worker to terminate, blocking until all the
work has been done.
class Queue {
bool finalizing;
condition ready;
condition done;
// add an item to the queue - called by a supplier thread
synchronized void add(int item) {
...add item to back of a queue...
ready = true;
}
// remove an item from the queue - called by a worker thread
synchronized int remove() {
waitfor (ready);
if (...queue is empty...) {
done = true;
throw new FinalisedException();
}
int item = ...remove item from front of queue...
ready = !(...queue is empty...) || finalizing;
return item;
}
// finalize the queue - normally called by the supplier thread
synchronized void finalize() {
finalizing = true;
ready = true;
waitfor (done; timeout_value);
if (!done)
throw new TimeoutException();
}
}
The compiler can do all the necessary stuff like:
* re-evaluating the condition after waking up, and waiting again if the
condition has been cleared by a critical race.
* making it an error to use conditions outside of synchronized methods.
I think this is much tidier than the Java approach, and it is certainly
a whole lot easier than using pthread conditions - even through a library.
More information about the Digitalmars-d
mailing list