Re: a really simple C++ abstraction around pthread_t...
On Oct 30, 10:39 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
Any suggestions on how I can improve this construct?
I think this construction is good enough for the moment. Now we should
turn to enhancing the communication part for shared objects in C++0x.
You know that Boost provides the scoped lock which has some advantage
over the explicit lock/unlock in Pthreads.
Furthermore, C++0x includes already some higher level wrapper
construct for making the wait for condition variables more natural or
user friendly. I refer to the wait wrapper, which expects the
predicate:
<quote>
template <class Predicate>
void wait(unique_lock<mutex>& lock, Predicate pred);
Effects:
As if:
while (!pred())
wait(lock);
</quote>
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html
</quote>
Actually, this wrapper could be combined with the scoped lock to get a
very high level construction in C++0x.
Well, ideally if they would dear to introduce some keywords in C++0x,
a bounded buffer could be expressed something like this.
template< typename T >
monitor class BoundedBuffer {
const unsigned int m_max;
std::deque<T> b;
public:
BoundedBuffer(const int n) : m_max(n) {}
void put(const T n) {
when (b.size() < m_max) {
b.push_back(n);
}
}
T get() {
T aux;
when (!b.empty()) {
aux = b.front();
b.pop_front();
}
return aux;
}
}
However, neither the `monitor' nor the `when' is not going to be
introduced in C++0x. The `when' would have the semantics of the
Conditional Critical Region.
Actually, something similar could be achieved with higher level
wrapper constructions that would result in program fragments like this
(I am not sure about the syntax, I did a simple transformation there):
template< typename T >
class BoundedBuffer : public Monitor {
const unsigned int m_max;
std::deque<T> b;
public:
BoundedBuffer(const int n) : m_max(n) {}
void put(const T n) {
{ When guard(b.size() < m_max);
b.push_back(n);
}
}
T get() {
T aux;
{ When guard(!b.empty());
aux = b.front();
b.pop_front();
}
return aux;
}
}
Here the super class would contain the necessary harness (mutex,
condvar) and the RAII object named `guard' could be similar to the
Boost scoped lock, it would provide locking and unlocking but in
addition it would wait in the constructor until the predicate is
satisfied. Something like this:
class When {
....
public:
When(...) {
// lock
// cv.wait(&lock, pred);
}
~When() {
// cv.broadcast
// unlock
}
};
The question is how would you hack the classes `Monitor' and `When' so
that active objects could be combined with this kind of monitor data
structure to complete the canonical example of producers-consumers.
Forget about efficiency concerns for now.
Best Regards,
Szabolcs