> First I would like to apologize if  what I am going to propose have
> already been suggested,  discussed and  rejected. If  that is  the case,
>  please  ignore this message.
>
> I would like to suggest a new interface (and implementation) for
> boost:thread. A problem with  the current version  (1.29.0), as  I see
> it,  is that it  does not distinguish between  the two  sides of  a
> thread. On  the one  side we  have the creation of a new thread and
> interaction with that thread, e.g.  joining. On the other  side we have
> the created  thread and  the operations  one might  want to perform
> there, e.g. yielding.

You can't "yield" another thread.  You can only "yield" the current
thread.  This is why yield() is static.

> True  that the  current implementation  of  boost:thread allows  you
> create  new threads,  interact  with the  thread  and  perform
> operations from  within  the thread. The problem is that it is all mixed
> in a single interface.

Which I don't think is a problem, and is what users would expect.

> If a created thread needs access to an instance of a boost::thread, then
> it must be handled in either of two ways.
>
> 1. The creating  side and the created thread  must share a single
> instance of a
>    boost::thread. For example:
>
>    boost::thread* thr ;
>
>    void thr_func()
>    {
>         thr->yield() ; // Yes I know that boost::thread::yield() is
> static.
>    }
>
>    int main()
>    {
>         thr = new boost::thread(thr_func) ;
>         thr->join() ;
>         delete thr ;
>    }
>
>    This solution has the obvious problem  of having to share common data
> between two separate threads of execution.
>
>
> 2. The other solution is that the created thread gets its own unique
> instance of
>    a boost::thread using the default ctor.
>
>    void thr_func()
>    {
>         boost::thread self ;
>         self.yield() ; // Once again, yes I know that yield() is static.
>    }
>
>    int main()
>    {
>         boost::thr thr(thr_func) ;
>         thr.join() ;
>    }
>
>    This  avoids the  problem of  having  to share  data between  two
> threads  of execution but  introduces another.  There is no
> association between  the two instances of boost::thread. This  makes
> it impossible to transfer information from the creating side to the
> created thread (yes, I know this is not part of the current
> boost::thread implementation but I think it should be).

No, it doesn't make it "impossible".  Passing data is accounted for in the
documentation, and is accomplished through the use of function objects. 
The Boost.Bind or Boost.Lambda libraries even make this trivial:

void my_thread(int val)
{
//....
}

boost::thread thrd(bind(&my_thread, 10));

> Another problem with a single interface  is the possibility of someone
> using the wrong member operation in the wrong context, e.g. calling
> join() from within the created thread. Yes, you would be stupid  if you
> made such a mistake but why not prevent it all together by a new
> interface to boost::thread.

Seperating the interfaces won't prevent mistakes like this.

> Yet  another problem with  the current  implementation is  that the
> header file exposes  implementation  specific  details.   This  makes it
>  very  likely  that modification  to  the implementation  or  adding
> support  for a  new  threading environment will require a re-compilation
>  of all code using boost::thread. Such implementation specific details
> should, if at all possible,  be hidden behind a pimple.

Discussed to death.  The PIMPL idiom has costs that are deamed too costly.

> What I would  like to see is a new boost::thread  implementation which
> meets the following requirements.
>
> a. There shall be two interfaces to a thread. One for creation of a
> thread, from
>    here on called  boost::thread. And, one for the created  thread, from
> here on called boost::thread::self.

Self?  Why?  If it's on operation that can *only* be made on the current
thread, then a static method is a better approach.  Otherwise, I could
make a "self" instance and pass it to another thread, which could then
attempt an operation that's not valid for calling on another thread.

> b. There shall  exist a  single, unique  association between  an
> instance  of  a
>    boost::thread and  an instance of a boost::thread::self.  This
> association is from here on called boost::thread::context.

If this is what I think it is, it's an implementation detail that
shouldn't be exposed to the user.

> c. It  shall be possible to  create instances of  boost::thread::self
> without an
>    associated instance  of boost::thread. This is  mainly useful if  one
> wants a boost::thread::self instance for the very first thread of
> execution, i.e. the thread which main() runs in.

I really don't comprehend how this would be useful.

> d. If one does not want to  perform any thread specific operations from
> within a
>    thread,  then  it  shall  not  be  necessary  to  create  an
> instance  of  a boost::thread::self.

True today.

> e. There  shall  be  no  parent-child  relationship  between  an
> instance  of  a
>    boost::thread and an instance of  a boost::thread::self, i.e.  a
> thread which starts yet another thread shall not be required to wait
> for that other thread and termination  of the  first thread  shall
> not lead  to termination  of the other thread.  This  means that an
> instance of a boost::thread  can go out of scope without affecting
> the associated instance of a boost::thread::self.
>
> f. It shall be possible to send extra information, as an optional extra
> argument
>    to the  boost::thread ctor, to the created  thread.
> boost::thread::self shall offer a method for retrieving this extra
> information. It is not required that this information be passed in a
> type-safe manner, i.e. void* is okay.

No, void* is NOT okay.  And again, the current design facilities passing
data in a _typesafe_ manner, and with no restrictions on the number of
"parameters".  When combined with Boost.Bind it makes parameter passing
much simpler than would be possible with a void* design, not to mention
the typesafety.  (Have I mentioned that typesafety is important?)

> g. It shall  be possible for a thread  to exit with a return value.  It
> shall be
>    possible for  the creating side to  retrieve, as a return  value from
> join(), that  value. It is  not required  that this  value be  passed
> in  a type-safe manner, i.e. void* is okay.

Again, I fully disagree with any void* design.  And return values are
possible today, via the same ideas used for passing data, though there's
no "convenience" library like Boost.Bind to help here.  Simplifying this
is planned, however.

> h. Explicit termination of a thread, i.e. by calling
> boost::thread::self::exit()
>    shall not lead to any resource-leaks.

Only possible by throwing an exception, and you don't need library support
for this.  I'm not saying that I won't add an exit(), only that there's
not a compelling reason for it, other than completeness of the library.

> i. Creation of  a new thread of  execution shall not require calls  to
> any other
>    method than the boost::thread ctor.

True today, so I don't know why you have this requirement here.

> j. The header file shall not expose any implementation specific details.

It doesn't, today.  I realize you're referring to PIMPL here, but that
doesn't mean that the current implementation gives users access to
implementation details.  And again, PIMPL has been discussed and
discarded.  Sorry.

> Some additional features I would like to see.
>
> k. It should be possible to control  the behavior of a new thread, e.g.
> schedule
>    policy, scheduling priority and contention scope.

Initial design in the thread_dev branch.

> l. It should be  possible to cancel a thread and for a  thread to
> control how is
>    shall respond to cancellations.

Again, thread_dev branch.

> m. Failure  in any operation should  be reported by throwing
> exceptions, not by
>    assertions.

*chuckles*  Hot topic.  You really don't want to open that can of worms. 
But the current library does throw exceptions.  Assertions are used only
for debugging diagnostics on things that simply should never happen unless
there's a bug in the Boost.Threads library.  (That said, it's possible
I've missed some error conditions that should be exceptions, especially on
the Win32 platforms where error conditions aren't documented.)

-- 
William E. Kempf
[EMAIL PROTECTED]


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to