$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Yuval Ronen (ronen_yuval_at_[hidden])
Date: 2004-12-09 15:50:34
I believe that we are going a bit off the topic here, but I'll go there with 
you.
What you are suggesting, is that what we now know as 'thread' will be 
transformed into 'thread_impl' and will be hidden from the user, which will 
only know about thread_ref (actually a shared_ptr<thread_impl>). First of 
all, in no way do I dismiss this proposal. But what is the difference 
between this and the current design? As explained in the Boost.Threads 
documantation, if the user wish to control the life-time of the thread 
object in such a way, he can always wrap it in shared_ptr himself. Do we 
want to force him to work this way?
Another thing: if we want a
     thread_ref current_thread();
function, how will it be implmented? I hope you don't mean the returned 
thread to be non-joinable (which is a bad idea also in the current design), 
so I'll assume you don't. To return a regular (joinable) thread we have to 
hold a copy of each shared_ptr<thread_impl> (increase the ref count by 1) in 
an internal singleton data structure. That adds a considerable amount of 
complexity to the implmentation, which is now nice and clean. It also raises 
some questions, such as: When do we release the internal reference and allow 
destruction of the thread_impl? Is it on join()? Maybe on thread execution 
end? What if a thread is never joined? I presume that all these questions 
can be reasonably answered, but still, it adds a factor of complexity.
The questions we have to ask ourselves are: Do we wan't to impose our memery 
management decisions on the user? Does having a tight control over the 
lifecycle of the thread object in the library's hand (rather than the 
user's) is that important? Do we want to pay for it with a much more complex 
implementation?
My personal opinion is to answer "no" to these questions. I'm quite fond 
with the current noncopyable design (except the things I dislike, of 
course), but that's just my opinion...
Note that both sides of the "noncopyable thread vs. shared_ptr thread_ref" 
controversy agree that the basic thread class should be noncopyable. The 
difference is: should it be wrapped in a shared_ptr before serving it to the 
user, or not. So if you'll allow me to return to my initial claim from a few 
messages ago, the thing is that a noncopyable class should not have an 
operator== because it's inconsistent with the noncopyable notion. In 
addition, the thread's no-parameteres constructor also violates this idea by 
making a copy (of the current thread), and even making a bad copy 
(non-joinable) of it... As a replacement, I'm suggesting the is_current() 
member method to fulfill all of our desires, whether the thread is 
shared_ptr<>ed or not.
"Peter Dimov" <pdimov_at_[hidden]> wrote in message 
news:004601c4de17$807d5cd0$6401a8c0_at_pdimov2...
> Yuval Ronen wrote:
>
> [...]
>
>> According to your proposition, if I understood correctly, there is no
>> no-parameters constructor to thread, and all threads are joinable.
>> This is exactly what I was preaching to in my suggestion, so there is
>> no argument between us there. The difference is that you offer to add
>> a new thread_id class which I think is of no use at all. You need to
>> add some kind of connection between class thread and class thread_id,
>>    something like: thread_id thread::get_thread_id(); // thread method
>> and then you'll go around and compare thread_ids. What for?
>
> For
>
>    thread_id get_current_thread_id();
>
> presumably.
>
>> If we agree that threads cannot be copied,
>
> We don't. More details below.
>
>> it means that each thread can be
>> represented by only one thread object. Pass the address of thread
>> objects and compare them, if you really want to. It'll give you the
>> exact same result.
>
> The problem with your reasoning is that the thread object may have been 
> destroyed. Its lifetime is not tied to the lifetime of the thread.
>
> Threads are noncopyable for historical reasons. Bill Kempf's original 
> design had copyable, reference counted threads. Beman Dawes argued that a 
> thread is conceptually very similar to an fstream, so it should be 
> noncopyable, and Bill found his arguments convincing enough. I argued for 
> what seemed like an eternity that this is wrong, and the user should never 
> see a thread "object", only a thread handle (tentatively called thread_ref 
> at the time) - essentially a shared_ptr<thread_impl>. The proposed API was
>
>    thread_ref create_thread( F f );
>    thread_ref current_thread();
>    void join( thread_ref tr );
>
> I was unable to convince Bill Kempf to change the design (back), however.