From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-08-30 11:53:23
From: "William Kempf" <williamkempf_at_[hidden]>
> From: "Peter Dimov" <pdimov_at_[hidden]>
> >The main thread is significantly different from other 'adopted' threads
> >assuming that such threads even exist. This is why it deserves special
> >Every program has a main thread. Many (most?) programs don't have adopted
> I understand the reasoning and the concern. The problem is, the
> is a very low level detail, part of the abstract machine, and the higher
> level libraries (POSIX and Win32) we have access to (rightfully) hide the
> differences and give us no way to differentiate the "initial thread" from
> any other. So, from an implementation stand point for Boost.Threads,
> can be no difference. I expect the standards folks to address this issue,
I don't think that the abstract machine has anything to do with it. The main
thread is created by the runtime, whereas additional threads are explicitly
created by user code via the native threading primitives.
Any dynamically initialized object with static storage duration will have
its initialization expression/constructor executed by the initial thread,
AFAICS. So the initial thread is very much detectable and 'special', without
any modifications to the abstract machine.
> We can still safely assume that "whoever created the thread will join or
> detach it". There's no requirement in either POSIX or Win32 for user code
> to "join" or "detach" the "initial thread". The abstract machine takes
> of this for you. You are right, however, that for both it's possible to
> specifically "join" the "initial thread", and Boost.Threads has lost this
> I don't know how to safely and acceptably allow this, and find it
> to be an acceptable loss. I really do feel that "joining" the "initial
> thread" is a design error, and if one insists on such a design they can
> accomplish it by having a "thread_main" that's the only thread spawned by
True for user code; unfortunately not an option for a thread_ref wrapper
> I'm not arguing that the "initial thread" isn't a special case, I'm
> that given the implementation constraints that Boost.Threads has, it can't
> treat it as a special case. The "initial thread" simply must be treated
> same as any other "adopted" thread.
Given the quality of your current implementation, I very much believe that
you can overcome the technical problems. ;-)
> >Without additional support from the runtime, the only requirement on the
> >user code is that the first call to create() or current() (or the first
> >attempt to construct a boost::thread) is made from the initial thread.
> >is quite reasonable.
> Well, I never thought of adopting the thread within create(). That does
> make things seem to be "quite reasonable". Unfortunately, legacy libraries
> can still cause holes in this if they spawn threads through native
> and these threads call into routines that call current(). I may be able
> fill the holes in here...
You can get very close, I believe. If the translation unit that contains
current()/create() (or alternatively the boost::thread constructor) has a
static object, its constructor is guaranteed to be executed before the first
call to a function in this translation unit. On nearly every implementation
this constructor will be executed by the initial thread, unless it's in a
.so, and the .so is loaded with dlopen() from within another thread... which
is a corner case.
Besides, I don't ask for an implementation that works all the time. I ask
for a specification that calls for an implementation that works.
> I haven't thought it through enough yet, but this
> functionality simply isn't in the submission and I hope it's not enough of
> an issue to warrant rejection (even on contingent changes) of the library.
> This is an extreme corner case and we can address it in the future.
Rejection, as I said, is not an option.
-- Peter Dimov Multi Media Ltd.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk