Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-08 15:35:38


--- In boost_at_[hidden], Dietmar Kuehl <dietmar_kuehl_at_y...> wrote:
> Hi,
>
> --- William Kempf <sirwillard_at_m...> wrote:
> > --- In boost_at_[hidden], scleary_at_j... wrote:
>
> > > IMO, pthreads is a good example of object-oriented C. Object =
> > data +
> > > related functions -> pthread_mutex_t + pthread_mutex_init,
> > > pthread_mutex_destroy, pthread_mutex_lock, ...
> >
> > Agreed, but this all implies too many restrictions on the OO
model.
> > The simplest example to give in this regard is the requirement
that
> > the thread creation routines take a function pointer and a void
> > pointer as arguments.
>
> I disagree with this being a restriction: This can be used to
implement
> whatever design we choose, including a base class with an overriden
> function being started. The function pointer used is internal to the
> implementation. Here is a potential implementation:
>
> extern "C" void* run_thread(void*);
>
> struct thread {
> void run() {
> if (pthread_create(&m_thread, &m_attr, run_tread ,this))
> throw "thread could not be created!";
> }
> // ...
>
> private:
> friend void* thread_run(void*);
> virtual int do_run() = 0;
>
> pthread_t m_thread;
> pthread_attr_t m_attr;
> };
>
> void* run_thread(void* obj) {
> pthread_exit(static_cast<thread*>(obj)->do_run());
> return 0;
> }
>
> With something like this, we have objects to be run and can easily
> create derived functions calling whatever kind of function object we
> want to call. ... and the pthreads interface is not at all
visible.

This is the "thin wrapper" that I dislike. Now we must derive from
thread (or in other implementation, derive from runnable or some
other suitably named secondary class) in order to be an "active
object" and the active object is the only form of thread routine
available. A thread creation routine that truly took C++ into
consideration would allow you to create a thread from any function or
any member function or even from some arbitrary functor. As the
caller I should be able to supply what ever arguments I want to to
the "routine" that runs in the thread. The C callback approach isn't
really appropriate in C++. Instead, think "slots for threads".

> > > In fact, the related functions map so well to member functions
that
> > > a wrapper class can be written almost without thought (error
> > > checking ommitted, but can be easily added):
> > > class mutex {
> > > private:
> > > pthread_mutex_t me;
> > > mutex(const mutex &);
> > > void operator=(const mutex &);
> > > public:
> > > mutex() { pthread_mutex_init(&me, 0); }
> > > ~mutex() { pthread_mutex_destroy(&me); }
> > > void lock() { pthread_mutex_lock(&me); }
> > > void unlock() { pthread_mutex_unlock(&me); }
> > > bool trylock() { return !pthread_mutex_trylock(&me); }
> > > };
>
> This is the kind of interfaces I want to avoid! You can lock the
mutex
> without automatic release. This wrapper is clearly too thin.

It's not a bad interface, and is in fact the proper starting point.
However, the lock and unlock routines probably should be private and
a nested class would be used to lock/unlock the mutex with "auto_ptr
like" semantics. This would likely mean that the "trylock"
functionality would need to throw an exception since we'd be using c-
tor/d-tor pairs to lock and unlock the mutex.

> > Is it possible to copy a mutex class?
>
> This was taken care of: The copy ctor and assignment are declared to
> be private and thus these objects can neither be copied nor
assigned.

I've got egg on my face. I looked specifically to see if he'd
addressed this issue and missed it! Time to clean my glasses off.

> This is, IMO, the right semantics. Possible, there could be
function to
> copy attributes like there is for IOStreams ('copyfmt()') to create
a
> mutex with identical attributes or to safe the attributes to be
> restored later but I don't think mutex can be copied.

I'm not sure I agree here. If the mutex isn't copyable this means
that any class that contains a mutex (to handle internal
synchronization) then the class is either not copyable or code must
be supplied within every such class to deal with the issue. Copy
semantics here have a lot of pros and cons and I think they'll need a
bit of discussion.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk