Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2001-06-27 11:30:05


From: <williamkempf_at_[hidden]>
> --- In boost_at_y..., williamkempf_at_h... wrote:
> > --- In boost_at_y..., Beman Dawes <bdawes_at_a...> wrote:
> > > At 10:03 AM 6/27/2001, williamkempf_at_h... wrote:
> >
> > > >Another thing I've thought of over night. This design makes it
> > > >impossible to have a self() method, but I think this
> > functionality is
> > > >a necessity.
> > >
> > > Yes, you said that before, but I still don't understand why you
> > don't just
> > > pass a thread ref or pointer to the initial thread function as an
> > > argument. Why isn't that satisfactory?
> >
> > class thread_group
> > {
> > public:
> > void push(thread* thrd);
> > void wait_all() {
> > // pseudo code
> > for each managed thread
> > {
> > if (managed thread == self)
> > throw;
> > }
> > }
> > };
> >
> > Being passed a reference to the thread in the thread's start
> routine
> > is not enough for this simple example. It's contrived, but it's
> > enough to illustrate the problem to good effect, I believe.
> >
> > Adding an is_current() to thread would take care of this case, but
> as
> > we add to the operations that can be performed on a thread, such as
> > setting its priority, the need for self() becomes greater. I
> > honestly don't think we can do with out this operation.
>
> Considering all of the discussion so far, I think this slightly
> modified interface is the best design so far:
>
> class thread : boost::noncopyable
> {
> public:
> thread(detail::threadproc proc); // Starts the thread

What happens if proc throws?

Do I have to reach down into thread::detail to declare my
proc, or will this eventually be templatatized to take any
function or function object of zero arguments?

> ~thread(); // If not detached, detaches the thread
>
> // Considering that this type is noncopyable, these
> // operations are probably not necessary, but I'll
> // leave them in for the sake of discussion.
> bool operator==(const thread& other) const;
> bool operator!=(const thread& other) const;
>
> // To allow us to not need self(), at least for
> // comparison.
> bool is_current() const;
>
> bool is_alive() const;
>
> // Waits for the thread to finish and then calls detach()
> void join();
> // Seperates the object from the actual thread of execution
> // allowing the thread to just "evaporate" when finished
> // or when the main thread of execution terminates.
> void detach();
>
> // I have a feeling this one should go away with this
> // design, but again I'll leave it in for discussion.
> static void join_all();
>
> // These two can probably become free standing methods,
> // though I like the encapsulation.
> static void sleep(const xtime& xt);
> static void yield();
> };
>
> As it stands, this design is very viable, and is the best of what's
> been discussed. My concerns are:
>
> 1) Will other operations that can be performed on threads create a
> very real need for a self() method?
> 2) Should there be a join_all(). I'm becoming convinced there
> shouldn't be for various reasons, but with this design in particular
> the semantics will become difficult to detail. The join_all() method
> was first suggested by Jeremy Siek and it certainly makes some things
> simpler to deal with given some other designs, but since we can't
> know which threads are running at the point of call it's a dangerous
> call to make any way.
> 3) Should there be comparison operators? With out copy semantics
> you'd always be comparing to yourself, so I'd guess not.
> 4) Will the usage of this design make users opt for the native C
> APIs instead of the Boost.Threads library. Even if the design is
> superior (I won't claim it is, though that was the goal of everyone
> here) if no one will use it then the design is a failure.
> 5) Are the join(), detach() and destructor semantics understandable
> and usable? For example, what happens if you call a method on a
> thread object that's been detached? I would expect an error. If
> that's the case should join() detach the thread, or simply wait for
> the thread to finish, being a noop if the thread is already
> finished? Should the destructor detach() the thread or join() it?
> 6) Should sleep() and yeild() be stand alone methods, and why?
> We'll need good rationale statements for this which ever route we
> go. The rationale for making them static methods is to give them
> access to thread internals, but both current target implementations
> do not have this need, and it's possible (probable?) that no
> implementation will need this.

If they are standalone where do the go?

> Bill Kempf
>
>
> Info: http://www.boost.org Unsubscribe: <mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>


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