Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mr Thread, please don't call terminate

57 views
Skip to first unread message

Frederick Gotham

unread,
Mar 12, 2020, 4:41:36 AM3/12/20
to

According to the C++11 Standard, if you create an object of type "std::thread" and start it running, then you must either 'join' or 'detach' before the destructor of the "std::thread" object is called, otherwise "std::terminate" gets called.

Are there any pitfalls to doing the following?

class Safe_Thread : public std::thread {
public:

~Safe_Thread(void)
{
std::thread::detach();
}
};

My aim here is to have a thread class that behaves exactly like "std::thread" (or indeed boost::thread) but which doesn't call std::terminate if you don't 'join' or 'detach'.

David Brown

unread,
Mar 12, 2020, 5:45:54 AM3/12/20
to
Yes, there are pitfalls. First, it's going to be bad for a thread
object that does not own a thread (such as after you've called detach,
or after you've moved the object, or after you've joined the thread).
Secondly, you are left with these threads hanging around that you can't
access and tidy up. Third, if you have started a thread, you have some
idea of what you want to do with it - such as join it or detach it.

Paavo Helde

unread,
Mar 12, 2020, 6:12:13 AM3/12/20
to
Your aim is understandable, but not very wise. A detached thread cannot
be joined, meaning that your program is basically not able to guarantee
a clean shutdown any more. Failing to join the threads properly is just
sloppy programming.

If you still insist on having detached threads, I suggest to use _exit()
for terminating the program, this will kill it on spot without any
cleanup of global statics etc, and so it should avoid any errors in the
still running threads. A decent OS will clean up the system resources
automatically when the process dies, so you might come off relatively
safe with this (unless the threads perform some externally visible tasks
like writing files, of course).



cda...@gmail.com

unread,
Mar 12, 2020, 8:01:49 AM3/12/20
to
So like my girlfriend dragged me to see Debbie Gibson play in San Jose. I was kind of shocked that the woman didn't have a big butt. This is because, like, a lot of women, past a certain age, like, tend to get a big ass.

cda...@gmail.com

unread,
Mar 12, 2020, 8:03:39 AM3/12/20
to
Going off on a tangent, when possible, I tend to use function callbacks instead of threads. I also tend to drink Mt. Dew instead of Diet Coke.

Öö Tiib

unread,
Mar 12, 2020, 10:35:44 AM3/12/20
to
Do whatever you want. Lousy management of most precious
resources like peripheral devices, processor cores, processes,
i/o sockets, file descriptors or threads of execution are symptoms
of usual trashware (that is over 95% of all programs).



Jorgen Grahn

unread,
Mar 12, 2020, 8:36:05 PM3/12/20
to
On Thu, 2020-03-12, Paavo Helde wrote:
> On 12.03.2020 10:41, Frederick Gotham wrote:
>>
>> According to the C++11 Standard, if you create an object of type
>> "std::thread" and start it running, then you must either 'join' or
>> 'detach' before the destructor of the "std::thread" object is
>> called, otherwise "std::terminate" gets called.
>>
>> Are there any pitfalls to doing the following?
>>
>> class Safe_Thread : public std::thread {
>> public:
>>
>> ~Safe_Thread(void)
>> {
>> std::thread::detach();
>> }
>> };
>>
>> My aim here is to have a thread class that behaves exactly like
>> "std::thread" (or indeed boost::thread) but which doesn't call
>> std::terminate if you don't 'join' or 'detach'.
>
> Your aim is understandable, but not very wise. A detached thread cannot
> be joined, meaning that your program is basically not able to guarantee
> a clean shutdown any more. Failing to join the threads properly is just
> sloppy programming.

And an extremely common flaw.

My gut feeling for threads is, you need to design thread lifetimes as
carefully as process lifetimes (for forked processes), and a worker
thread should probably accept a special work request that says "please
exit".

(But that gut feeling is just based on experience dealing with bad
designs. I avoid threads myself.)

> If you still insist on having detached threads, I suggest to use _exit()
> for terminating the program, this will kill it on spot without any
> cleanup of global statics etc, and so it should avoid any errors in the
> still running threads.

How about std::quick_exit()?

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Paavo Helde

unread,
Mar 13, 2020, 3:11:52 AM3/13/20
to
On 13.03.2020 2:35, Jorgen Grahn wrote:
> On Thu, 2020-03-12, Paavo Helde wrote:
>> If you still insist on having detached threads, I suggest to use _exit()
>> for terminating the program,
>
> How about std::quick_exit()?

Yes, that's the same as far as I can see.


Paavo Helde

unread,
Mar 13, 2020, 3:15:30 AM3/13/20
to
On 13.03.2020 2:35, Jorgen Grahn wrote:
> On Thu, 2020-03-12, Paavo Helde wrote:
>> Failing to join the threads properly is just
>> sloppy programming.
>
> And an extremely common flaw.
>
> My gut feeling for threads is, you need to design thread lifetimes as
> carefully as process lifetimes (for forked processes), and a worker
> thread should probably accept a special work request that says "please
> exit".

Not necessarily. If the thread is carrying out a specific task and will
terminate by itself after that, then all what's needed is to join it in
the main thread before ending the program. The join operation will just
wait until the worker thread is completed.

David Brown

unread,
Mar 13, 2020, 5:57:01 AM3/13/20
to
It all depends on what kind of thread it is - a one-off thread that does
something and exits, or one that lives for a long time and has to be
told to die.

Outside of simple test examples, I don't think it is common to have
threads that just run a job then exit themselves (and can be cleared up
with a join). If you have work to do in parallel or in the background,
then a pool of worker threads is more useful and avoids the overhead of
creating and destroying threads. In that case, the final "task" you
send to each thread is "please exit".

Chris M. Thomasson

unread,
Mar 13, 2020, 6:18:20 PM3/13/20
to
On 3/12/2020 5:35 PM, Jorgen Grahn wrote:
> On Thu, 2020-03-12, Paavo Helde wrote:
>> On 12.03.2020 10:41, Frederick Gotham wrote:
[...]
> My gut feeling for threads is, you need to design thread lifetimes as
> carefully as process lifetimes (for forked processes), and a worker
> thread should probably accept a special work request that says "please
> exit".

Indeed. Works like a charm.

Fwiw, I remember doing something experimental a long time ago where a
group of spawned threads working on a task could enqueue a single work
request which meant that everything is finished. Only one thread in the
group would do this. Then, when the work request was picked up by a main
worker thread, it would join the spawned threads in the group, examine
the result, and do whatever, then go back into the worker event loop.

[...]

Chris M. Thomasson

unread,
Mar 13, 2020, 6:22:07 PM3/13/20
to
Fwiw, detached threads are most likely: evil... This reminds me of
discussions over on comp.programming.thread from a long time ago, early
2000's.
0 new messages