Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-06-27 16:39:00


--- In boost_at_y..., "Greg Colvin" <gcolvin_at_u...> wrote:
> From: <williamkempf_at_h...>
> >...
> > Let me summarize the two main interfaces that people seem to
think
> > are the best, and try and flesh them out completely, adding more
> > questions as I go.
>
> Thanks for this clear exposition.

Thanks. I hope I captured the best of both designs and covered all
the bases.

> There is (at least) a third,
> combined possibility (leaving aside free versus member functions).
> It has the possible advantage of not requiring any overhead for
> reference counting or heap allocation when the thread::ref interface
> is not needed. It has the disadvantage of redundancy.
>
> class thread : noncopyable
> {
> public:
>
> class ref
> {
> public:
> ref();
> ref(const ref& other);
> ~ref();
>
> ref& swap(const ref& other);
> ref& operator=(const ref& other);
>
> bool operator==(const ref& other) const;
> bool operator!=(const ref& other) const;
>
> bool is_current() const;
> bool is_alive() const;
>
> void join();
> };
>
> static ref create(boost::function1<void>);
> static void sleep(const xtime& xt);
> static void yield();
>
>
> thread(boost::function1<void>); // start a thread running
> ~thread(); // detach from thread if still running
>
> bool is_current() const;
> bool is_alive() const;
> void join();
> };
>
> The only easy way I see to avoid the redundancy is
>
> class thread : noncopyable
> {
> public:
>
> static shared_ptr<thread> create(boost::function1<void>);
>
> static void sleep(const xtime& xt);
> static void yield();
>
> thread(boost::function1<void>); // start a thread running
> ~thread(); // detach from thread if still running
>
> bool is_current() const;
> bool is_alive() const;
> void join();
> };
>
> Although the above would require a thread-safe shared_ptr that
> might be less efficient than the native handle, so perhaps it
> should be:
>
> class thread : noncopyable
> {
> public:
>
> class ptr
> {
> public:
> thread* operator->();
> ...
> };
>
> static ptr create(boost::function1<void>);
>
> ...
> };
>
> How important it is that Gary not pay for (possible) reference
> counting he doesn't need I don't know, so I'll leave it to
> Gary to actually argue for one of these if he wants. I remain
> satisfied with interface 2.

These are all syntactic variations on one design (as you know), and
the key to focus on here is the syntax using the shared_ptr. This
gives us creation syntax like this:

shared_ptr<thread> p(thread::create(proc));

This is nearly identical to the more intuitive syntax:

shared_ptr<thread> p(new thread(proc));

In other words, I see absolutely no benefit to this third design.

To me the decision comes down to a simple question. Do we need a self
() method? If we do, we must go with "Interface 2" since it's the
only one that will allow for a self() method. If we don't, we should
probably opt for "Interface 1" since it's conceptually a cleaner C++
design and easily allows for ref-counted usage through the above
syntax with no modifications to the interface.

Bill Kempf


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