Topic: Does ~thread() implicitly detatch?


Author: Pete Becker <pete@versatilecoding.com>
Date: Wed, 1 Jul 2009 11:31:50 CST
Raw View
Scott Meyers wrote:
> Is there any difference in semantics between this
>
>    void someFunction();
>
>    void f()
>    {
>      std::thread t(someFunction);
>      t.detach();
>    }
>
> and this?
>
>    void f()
>    {
>      std::thread t(someFunction);
>    }                                   // implicit detach?
>
> In the draft of his "C++ Concurrency in Action," Anthony Williams writes:
>
>> ...one way to detach a thread is just to destroy the associated
>> std::thread object. This is fine for those circumstances where you can
>> destroy the std::thread object,
>> either because it is a local object and is destroyed when the
>> containing scope is exited...
>
> This suggests that the two functions above are equivalent.  But the draft
> standard (N2914) says this about std::thread's destructor:
>
>> [ Note: Either implicitly detaching or joining a joinable() thread in
>> its destructor could result in
>> difficult to debug correctness (for detach) or performance (for join)
>> bugs encountered only when an
>> exception is raised. Thus the programmer must ensure that the
>> destructor is never executed while the
>> thread is still joinable.     end note ]
>
> Okay, notes aren't normative, and the emphasis is mine, but "the
> programmer MUST
> ensure that the destructor is never executed while the thread is still
> joinable"
> sounds strident enough to me that I worry there are teeth behind it.
>
> Is destroying a thread object semantically equivalent to calling detach
> on it?
>

It looks like there are some words missing from the draft there. There
was a change made at the Summit meeting to make destruction of a
joinable thread call terminate().

--
    Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Wed, 1 Jul 2009 23:05:05 CST
Raw View
On Jul 1, 4:36 am, Scott Meyers <use...@aristeia.com> wrote:

> Is destroying a thread object semantically equivalent to calling detach on it?

It used to be.  N2802 (alternative 2) modified the behavior of ~thread
().  I believe the current WP is missing a sentence specified by N2802
in the description of ~thread().  I have notified the project editor.
The missing sentence is:

If joinable() then terminate(), otherwise no effects.

-Howard


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <usenet@aristeia.com>
Date: Wed, 1 Jul 2009 02:36:25 CST
Raw View
Is there any difference in semantics between this

    void someFunction();

    void f()
    {
      std::thread t(someFunction);
      t.detach();
    }

and this?

    void f()
    {
      std::thread t(someFunction);
    }                                   // implicit detach?

In the draft of his "C++ Concurrency in Action," Anthony Williams writes:

> ...one way to detach a thread is just to destroy the associated
> std::thread object. This is fine for those circumstances where you can destroy the std::thread object,
> either because it is a local object and is destroyed when the containing scope is exited...

This suggests that the two functions above are equivalent.  But the draft
standard (N2914) says this about std::thread's destructor:

> [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in
> difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an
> exception is raised. Thus the programmer must ensure that the destructor is never executed while the
> thread is still joinable.   end note ]

Okay, notes aren't normative, and the emphasis is mine, but "the programmer MUST
ensure that the destructor is never executed while the thread is still joinable"
sounds strident enough to me that I worry there are teeth behind it.

Is destroying a thread object semantically equivalent to calling detach on it?

Thanks,

Scott


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Wed, 1 Jul 2009 09:59:55 CST
Raw View
Scott Meyers <usenet@aristeia.com> writes:

> Is there any difference in semantics between this
>
>    void someFunction();
>
>    void f()
>    {
>      std::thread t(someFunction);
>      t.detach();
>    }
>
> and this?
>
>    void f()
>    {
>      std::thread t(someFunction);
>    }                                   // implicit detach?

Yes. The second does not do an implicit detach. The second calls std::terminate.

> In the draft of his "C++ Concurrency in Action," Anthony Williams writes:
>
>> ...one way to detach a thread is just to destroy the associated
>> std::thread object. This is fine for those circumstances where you can destroy the std::thread object,
>> either because it is a local object and is destroyed when the containing scope is exited...

That was written before the March 2009 WG21 meeting, at which the
destructor was changed to call terminate. The paper which proposed the
change was N2802:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2802.html

> This suggests that the two functions above are equivalent.  But the draft
> standard (N2914) says this about std::thread's destructor:
>
>> [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in
>> difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an
>> exception is raised. Thus the programmer must ensure that the destructor is never executed while the
>> thread is still joinable.           end note ]
>
> Okay, notes aren't normative, and the emphasis is mine, but "the programmer MUST
> ensure that the destructor is never executed while the thread is still joinable"
> sounds strident enough to me that I worry there are teeth behind it.
>
> Is destroying a thread object semantically equivalent to calling detach on it?

No. As described above, this *was* the case, but this has now been
changed: destroying a thread object without joining or detaching calls
std::terminate.

Anthony
--
Author of C++ Concurrency in Action | http://www.manning.com/williams
just::thread C++0x thread library   | http://www.stdthread.co.uk
Just Software Solutions Ltd         | http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Wed, 1 Jul 2009 10:01:13 CST
Raw View
On Jul 1, 10:36 am, Scott Meyers <use...@aristeia.com> wrote:
> Is there any difference in semantics between this

>     void someFunction();

>     void f()
>     {
>       std::thread t(someFunction);
>       t.detach();
>     }

> and this?

>     void f()
>     {
>       std::thread t(someFunction);
>     }                                   // implicit detach?

Maybe.  It depends on which draft you look at.  The latest draft
doesn't have an Effects clause for thread::~thread(), so we
don't know.  The preceding draft did have an Effects: clause,
which said "If joinable() then detach() terminate()".  The only
"terminate()" I can find is std::terminate(), so presumably,
according the the next to the last draft, the second should
abort the program.  The CD (still an earlier draft) says the
same thing without the terminate, so the two would be equivalent
there.

> In the draft of his "C++ Concurrency in Action," Anthony
> Williams writes:

> > ...one way to detach a thread is just to destroy the
> > associated std::thread object. This is fine for those
> > circumstances where you can destroy the std::thread object,
> > either because it is a local object and is destroyed when
> > the containing scope is exited...

Which corresponds to boost::threads and some earlier drafts.
This is a known design flaw in boost::threads, however, and
presumably, the standards committee is still trying to decide on
the best way to solve it.  (IMHO, the best way of solving it
would start with two different ways of managing threads: a
thread class for joinable threads, in which calling the
destructor before the join is a programming error, and a free
function to start a detached thread.)

> This suggests that the two functions above are equivalent.
> But the draft standard (N2914) says this about std::thread's
> destructor:

> > [ Note: Either implicitly detaching or joining a joinable()
> > thread in its destructor could result in difficult to debug
> > correctness (for detach) or performance (for join) bugs
> > encountered only when an exception is raised. Thus the
> > programmer must ensure that the destructor is never executed
> > while the thread is still joinable.   end note ]

> Okay, notes aren't normative, and the emphasis is mine, but
> "the programmer MUST ensure that the destructor is never
> executed while the thread is still joinable" sounds strident
> enough to me that I worry there are teeth behind it.

> Is destroying a thread object semantically equivalent to
> calling detach on it?

Again, it depends on which version of the draft you read (which
suggests that the issue is still being discussed).  I don't
think you should count on the implicit detach, however.  (The
problem isn't when you want a detached thread; creating a thread
and then just forgetting about it is actually a rather nice
idiom for detached threads.  The problem is when you want to
join, but an exception occurs, causing the joinable thread to
unexpectedly become detached.)

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient  e objet/
                    Beratung in objektorientierter Datenverarbeitung
9 place S  mard, 78210 St.-Cyr-l'  cole, France, +33 (0)1 30 23 00 34


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Ric Parkin <ric.parkin@gmail.com>
Date: Wed, 1 Jul 2009 11:20:33 CST
Raw View
On 1 July, 09:36, Scott Meyers <use...@aristeia.com> wrote:
> Is there any difference in semantics between this
>
>     void someFunction();
>
>     void f()
>     {
>       std::thread t(someFunction);
>       t.detach();
>     }
>
> and this?
>
>     void f()
>     {
>       std::thread t(someFunction);
>     }                                   // implicit detach?

> In the draft of his "C++ Concurrency in Action," Anthony Williams writes:
>
> > ...one way to detach a thread is just to destroy the associated
> > std::thread object. This is fine for those circumstances where you can destroy the std::thread object,
> > either because it is a local object and is destroyed when the containing scope is exited...
>
> This suggests that the two functions above are equivalent.  But the draft
> standard (N2914) says this about std::thread's destructor:
>
> > [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in
> > difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an
> > exception is raised. Thus the programmer must ensure that the destructor is never executed while the
> > thread is still joinable.   end note ]
>
> Okay, notes aren't normative, and the emphasis is mine, but "the programmer MUST
> ensure that the destructor is never executed while the thread is still joinable"
> sounds strident enough to me that I worry there are teeth behind it.
>
> Is destroying a thread object semantically equivalent to calling detach on it?

I believe this changed recently, hence the contradiction.

It used to be that the destructor automatically called detatch, but
now it will call std::terminate unless it has been explicitly
detatched or joined.

Hans' paper discussing the issue is here
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2802.html

And I can find references that alternative 2 - terminate - was
adopted. Here's the minutes:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2847.html

Ric



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]