Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #79723 > unrolled thread

Re: std::thread does not follow RAII principles

Started byMrSpook_ry@939_6htz773e0qeya.eu
First post2021-05-27 08:18 +0000
Last post2021-05-28 11:11 +0000
Articles 20 on this page of 54 — 11 participants

Back to article view | Back to comp.lang.c++

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: std::thread does not follow RAII principles MrSpook_ry@939_6htz773e0qeya.eu - 2021-05-27 08:18 +0000
    Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 11:02 +0200
      Re: std::thread does not follow RAII principles MrSpook_b28s@jxgz6zklebr1.tv - 2021-05-27 10:24 +0000
        Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 12:33 +0200
          Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 12:40 +0200
            Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 12:55 +0200
          Re: std::thread does not follow RAII principles MrSpook_d4c3Jb7l7@8dftupdzk09cop2.co.uk - 2021-05-27 11:05 +0000
            Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 13:14 +0200
              Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 13:18 +0200
              Re: std::thread does not follow RAII principles MrSpook_b_x@ukpge.org - 2021-05-27 15:54 +0000
                Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-27 19:32 +0200
                  Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-27 19:00 +0100
                    Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-27 17:52 -0700
                      Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 05:24 +0200
                        Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 05:27 +0200
                      Re: std::thread does not follow RAII principles Ian Collins <ian-news@hotmail.com> - 2021-05-28 14:59 +1200
                        Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-27 20:37 -0700
                          Re: std::thread does not follow RAII principles Ian Collins <ian-news@hotmail.com> - 2021-05-28 16:50 +1200
                            Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 06:53 +0200
                            Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-27 23:07 -0700
                              Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 08:26 +0200
                              Re: std::thread does not follow RAII principles Ian Collins <ian-news@hotmail.com> - 2021-05-28 21:01 +1200
                                Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 13:04 +0200
                                  Re: std::thread does not follow RAII principles Branimir Maksimovic <branimir.maksimovic@gmail.com> - 2021-05-28 17:06 +0000
                                    Re: std::thread does not follow RAII principles scott@slp53.sl.home (Scott Lurndal) - 2021-05-28 17:51 +0000
                                      Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 20:00 +0200
                                      Re: std::thread does not follow RAII principles Branimir Maksimovic <branimir.maksimovic@gmail.com> - 2021-05-28 21:42 +0000
                              Re: std::thread does not follow RAII principles Branimir Maksimovic <branimir.maksimovic@gmail.com> - 2021-05-28 17:03 +0000
                    Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 03:55 +0200
                      Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-28 12:02 +0100
                        Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 13:15 +0200
                          Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-28 12:40 +0100
                            Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 13:55 +0200
                              Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 13:57 +0200
                                Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-28 14:29 +0100
                                  Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 15:48 +0200
                                    Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 16:16 +0200
                                      Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-28 15:45 +0100
                                        Re: std::thread does not follow RAII principles Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 17:30 +0200
                                          Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-28 19:54 +0100
                                    Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-28 15:08 +0100
                          Re: std::thread does not follow RAII principles Branimir Maksimovic <branimir.maksimovic@gmail.com> - 2021-05-28 17:08 +0000
                        Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-29 01:42 -0700
                          Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-29 13:05 +0100
                            Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-29 13:44 +0100
                              Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-29 06:34 -0700
                                Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-29 14:48 +0100
                                  Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-29 07:59 -0700
                                    Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-29 18:15 +0100
                                      Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-29 19:03 -0700
                                        Re: std::thread does not follow RAII principles Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-05-30 11:48 +0100
                                          Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-30 09:35 -0700
                            Re: std::thread does not follow RAII principles Öö Tiib <ootiib@hot.ee> - 2021-05-29 06:51 -0700
                  Re: std::thread does not follow RAII principles MrSpook_jx@zp238i0_j1.net - 2021-05-28 11:11 +0000

Page 1 of 3  [1] 2 3  Next page →


#79723 — Re: std::thread does not follow RAII principles

FromMrSpook_ry@939_6htz773e0qeya.eu
Date2021-05-27 08:18 +0000
SubjectRe: std::thread does not follow RAII principles
Message-ID<s8nkl1$avc$1@gioia.aioe.org>
On Wed, 26 May 2021 19:04:56 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> pthreads are really poor. F.e. having the opportunity to pass
>
>> Really? Want to have a guess what the C++ threading library on Linux uses?
>
>We don't discuss physical threading but how the language presents
>threading; and C++11-threading is by far more convenient than pure
>pthreads.

A Big Mac is convenient, doesn't make it the best meal. The pthreads library
is extremely powerful, perhaps the boiler plate setup code can be a bit long
winded but its not hard to use.

[toc] | [next] | [standalone]


#79725

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 11:02 +0200
Message-ID<s8nn6h$3je$1@dont-email.me>
In reply to#79723
> A Big Mac is convenient, doesn't make it the best meal. ...

Programming pthreads directly has no advantages
and makes a lot of workd more.

[toc] | [prev] | [next] | [standalone]


#79733

FromMrSpook_b28s@jxgz6zklebr1.tv
Date2021-05-27 10:24 +0000
Message-ID<s8ns0q$1q7m$1@gioia.aioe.org>
In reply to#79725
On Thu, 27 May 2021 11:02:11 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> A Big Mac is convenient, doesn't make it the best meal. ...
>
>Programming pthreads directly has no advantages

Presumably you've never had to use 3 level locking or fine grain threading
control. Also the lack of proper interoperability with signals makes C++ 
threading on unix a bit of a toy frankly.

>and makes a lot of workd more.

A bit, not a lot.

[toc] | [prev] | [next] | [standalone]


#79734

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 12:33 +0200
Message-ID<s8nshp$72b$1@dont-email.me>
In reply to#79733
> Presumably you've never had to use 3 level locking or fine grain threading
> control. Also the lack of proper interoperability with signals makes C++
> threading on unix a bit of a toy frankly.

Signals are a plague. You can't write a libary which does have a
Signal-handling which is coordinatet independently from the code
it is later embedded into. Both have to be made of a single piece.
Signals are even more worse since there can't be different handlers
for synchonous signals for different threads.
And signal-codd always have a reentrancy problem, that makes them
a even bigger plague. And the ABI has to be designed around them
(red zone). That's not clean coding.
Therefore: Outsource asynchronous signals to differnt threads.
Windows has a more powerful handling for something like synchronous
signals, Structured Excetion Handling. And for the few asynchronous
signals Windows knows, Windows spawns a diffrent thread if a signal
happens.

And which threading-contol is needed beyond that what C++ provides ?

[toc] | [prev] | [next] | [standalone]


#79735

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 12:40 +0200
Message-ID<s8nsub$9dc$1@dont-email.me>
In reply to#79734
>> Presumably you've never had to use 3 level locking or fine grain 
>> threading
>> control. Also the lack of proper interoperability with signals makes C++
>> threading on unix a bit of a toy frankly.

> Signals are a plague....
And even more: If I use C++-threading the places where signals could
occur and where I can't get the EAGAIN are only where I have locking
and / or waiting for a condition_variable. But the places where I
lock a mutex or wait for a CV with pthreads, Posix mandates you to
re-lock the mutex or re-wait for the CV - that's exactly what C++11
-synhroni-zation does also - so there's no difference here. So what
do you complain here ?

[toc] | [prev] | [next] | [standalone]


#79736

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 12:55 +0200
Message-ID<s8ntqb$dkv$1@dont-email.me>
In reply to#79735
> And even more: If I use C++-threading the places where signals could
> occur and where I can't get the EAGAIN are only where I have locking
> and / or waiting for a condition_variable. But the places where I
> lock a mutex or wait for a CV with pthreads, Posix mandates you to
> re-lock the mutex or re-wait for the CV - that's exactly what C++11
> -synhroni-zation does also - so there's no difference here. So what
> do you complain here ?

Oh, I'm partitially wrong here: pthread_mutex_wait behaves as described
_but_ pthread_cond_wait handles the signal-handler internally and con-
tinues waiting afterwards.
So there's still nothing different than with C+11-threads !

[toc] | [prev] | [next] | [standalone]


#79737

FromMrSpook_d4c3Jb7l7@8dftupdzk09cop2.co.uk
Date2021-05-27 11:05 +0000
Message-ID<s8nudr$vpq$1@gioia.aioe.org>
In reply to#79734
On Thu, 27 May 2021 12:33:28 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> Presumably you've never had to use 3 level locking or fine grain threading
>> control. Also the lack of proper interoperability with signals makes C++
>> threading on unix a bit of a toy frankly.
>
>Signals are a plague. You can't write a libary which does have a

Says the windows programmer.

>Signal-handling which is coordinatet independently from the code

Good, libraries should not be handling signals.

>Therefore: Outsource asynchronous signals to differnt threads.

You simply have a signal handling thread that sits in sigwait() and block
signals to everything else using pthread_sigmask(SIG_BLOCK...) which - 
surprise! - you can't do in C++ threads.

>Windows has a more powerful handling for something like synchronous
>signals, Structured Excetion Handling. And for the few asynchronous
>signals Windows knows, Windows spawns a diffrent thread if a signal
>happens.

Spawning a new thread for every signal isn't powerful , its moronic.

>And which threading-contol is needed beyond that what C++ provides ?

I'm not going to keep repeating myself, you appear to be wilfully deaf.

[toc] | [prev] | [next] | [standalone]


#79738

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 13:14 +0200
Message-ID<s8nuut$ml4$1@dont-email.me>
In reply to#79737
>> Signals are a plague. You can't write a libary which does have a

> Says the windows programmer.

Signals are simply a bad concept. No one would invent them today.

>> Signal-handling which is coordinatet independently from the code

> Good, libraries should not be handling signals.

The problem is that they partitially need. And that's not possible
without coordination with the code the're embedded into.

>> Therefore: Outsource asynchronous signals to differnt threads.

> You simply have a signal handling thread that sits in sigwait() and
> block signals to everything else using pthread_sigmask(SIG_BLOCK...)
> which - surprise! - you can't do in C++ threads.

Of course you could call sigwait() from a C++11-thread.

>> Windows has a more powerful handling for something like synchronous
>> signals, Structured Excetion Handling. And for the few asynchronous
>> signals Windows knows, Windows spawns a diffrent thread if a signal
>> happens.

> Spawning a new thread for every signal isn't powerful , its moronic.

That absolutely doesn't matter since the signals Windows knows are
very infreqiernt.

>> And which threading-contol is needed beyond that what C++ provides ?

> I'm not going to keep repeating myself, you appear to be wilfully deaf.

You are ultimately stupid !

[toc] | [prev] | [next] | [standalone]


#79739

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 13:18 +0200
Message-ID<s8nv62$ml4$2@dont-email.me>
In reply to#79738
> The problem is that they partitially need. And that's not possible
> without coordination with the code the're embedded into.

Imagine you've got two framworks with two configuration-files which
are refreshed through SIGUP - that's not possible without central
coordination.
Or imagine you've a application which does asynchronous I/O and a
include libary that does it as well. Handling SIGIO and passs the
results back to the originating threads can be a complex task. And
both must be coordinated centrally as there coudln't be any indi-
vidual signal-handlers.

Signals are simply a weak concept.

[toc] | [prev] | [next] | [standalone]


#79752

FromMrSpook_b_x@ukpge.org
Date2021-05-27 15:54 +0000
Message-ID<s8ofbl$1an0$1@gioia.aioe.org>
In reply to#79738
On Thu, 27 May 2021 13:14:36 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> Signals are a plague. You can't write a libary which does have a
>
>> Says the windows programmer.
>
>Signals are simply a bad concept. No one would invent them today.

Behold! Our mighty sage has spoken - let it be known that interrupts are a bad
idea!

Whatever you say sweetie.

[toc] | [prev] | [next] | [standalone]


#79778

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-27 19:32 +0200
Message-ID<s8ol4c$7ig$1@dont-email.me>
In reply to#79752
>> Signals are simply a bad concept. No one would invent them today.

> Behold! Our mighty sage has spoken - let it be known that interrupts are a bad
> idea!

Interrupts in userland with reentrancy-constraints a very bad idea.
And interrupting OS-calls with signals makes the operating-system
design very complex if you really want to make it interruptible at
every time while processing a call. That's not necessary if you'd
design it not that stupid.

[toc] | [prev] | [next] | [standalone]


#79787

FromChris Vine <chris@cvine--nospam--.freeserve.co.uk>
Date2021-05-27 19:00 +0100
Message-ID<20210527190000.513390cffd366ff30deb7a13@cvine--nospam--.freeserve.co.uk>
In reply to#79778
On Thu, 27 May 2021 19:32:58 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >> Signals are simply a bad concept. No one would invent them today.
> 
> > Behold! Our mighty sage has spoken - let it be known that interrupts are a bad
> > idea!
> 
> Interrupts in userland with reentrancy-constraints a very bad idea.
> And interrupting OS-calls with signals makes the operating-system
> design very complex if you really want to make it interruptible at
> every time while processing a call. That's not necessary if you'd
> design it not that stupid.

Interrupts were necessary with single-threaded programs.  They are not
usually necessary with multi-threaded programs and POSIX provides
everything you need in consequence.  You block the signals of interest
in all your threads and then have a single handler thread with blocks
on sigwait() and deals with the signals synchronously (synchronously
for the handler thread that is).  Job done.

One other thing POSIX provides and C++11 doesn't is thread cancellation.
Some programmers who don't have relevant experience think thread
cancellation is a bad idea because it allows arbitrary cancellation
which cannot be adequately controlled (the "combing your hair with a
fork" jibe).  Whilst that is true with windows it absolutely isn't with
POSIX.  What you do is use deferred cancellation (the default in POSIX)
and block cancellation as normal policy, and only enable cancellation
at defined points in the code which are able to deal with it (normally
where a wait is to occur).  Done properly, thread cancellation is far
easier to use than exceptions, which can jump out of anywhere if you
include std::bad_alloc in the mix.  C++11 threads don't deal with
cancellation and will never be able to do so because they require OS
support - in this case POSIX support.

[toc] | [prev] | [next] | [standalone]


#79820

FromÖö Tiib <ootiib@hot.ee>
Date2021-05-27 17:52 -0700
Message-ID<d9f55950-a420-4063-a4ca-86a1cc8a6803n@googlegroups.com>
In reply to#79787
On Thursday, 27 May 2021 at 21:00:13 UTC+3, Chris Vine wrote:
> On Thu, 27 May 2021 19:32:58 +0200 
> Bonita Montero <Bonita....@gmail.com> wrote: 
> > >> Signals are simply a bad concept. No one would invent them today. 
> > 
> > > Behold! Our mighty sage has spoken - let it be known that interrupts are a bad 
> > > idea! 
> > 
> > Interrupts in userland with reentrancy-constraints a very bad idea. 
> > And interrupting OS-calls with signals makes the operating-system 
> > design very complex if you really want to make it interruptible at 
> > every time while processing a call. That's not necessary if you'd 
> > design it not that stupid.
> Interrupts were necessary with single-threaded programs. They are not 
> usually necessary with multi-threaded programs and POSIX provides 
> everything you need in consequence. You block the signals of interest 
> in all your threads and then have a single handler thread with blocks 
> on sigwait() and deals with the signals synchronously (synchronously 
> for the handler thread that is). Job done. 
> 
> One other thing POSIX provides and C++11 doesn't is thread cancellation. 
> Some programmers who don't have relevant experience think thread 
> cancellation is a bad idea because it allows arbitrary cancellation 
> which cannot be adequately controlled (the "combing your hair with a 
> fork" jibe). Whilst that is true with windows it absolutely isn't with 
> POSIX. What you do is use deferred cancellation (the default in POSIX) 
> and block cancellation as normal policy, and only enable cancellation 
> at defined points in the code which are able to deal with it (normally 
> where a wait is to occur). Done properly, thread cancellation is far 
> easier to use than exceptions, which can jump out of anywhere if you 
> include std::bad_alloc in the mix. C++11 threads don't deal with 
> cancellation and will never be able to do so because they require OS 
> support - in this case POSIX support.

With that thread cancellation I'm always in doubt. Especially if discussed
in context of RAII and destructor of thing like std::thread. 

One of major reasons making a thread is to turn synchronous work into
asynchronous. For that we put it into thread so then synchronous work is
going on in thread doing its blocking operations (potentially checking if
the work has become obsolete and/or reporting progress between those)
and once complete (or failed) handing the results back over to caller thread.
That way the caller thread has all benefits of asynchronous works going on.
It is fully responsive, so can take care of other responsibilities, entertain
users, report progresses, mark ongoing works obsolete and/or put out the
results (or failures) once something becomes complete.

But what is that cancellation? It is like telling to worker thread to die in
middle of unknown state potentially in kernel with unknown amount of
locks taken, files open or mapped to virtual memory, that fragile external
hardware device produced by random morons in middle of something
and what not? std::terminate feels better and more honest than to cancel
the thread ... at least our users will see that we screwed all up in major
way. It all gets of course lost in examples because these talk about "foo()".

[toc] | [prev] | [next] | [standalone]


#79835

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-28 05:24 +0200
Message-ID<s8pnq8$peb$1@dont-email.me>
In reply to#79820
> If you want to manage resources in a thread that may be cancelled, you 
> can use cleanup functions.  I haven't tried it in Linux, but certainly 
> in Solaris, the C++ runtime will destroy objects if the creating thread 
> is cancelled. ...

With Linux that doesn't work:

#include <iostream>
#include <limits>
#include <pthread.h>
#include <unistd.h>

using namespace std;

struct destr
{
	~destr();
};

destr::~destr()
{
	cout << "destr::~destr()" << endl;
}

int main()
{
	auto thr = []( void * ) -> void *
	{
		cout << "thread is running" << endl;
		int oldStat;
		if(    pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, &oldStat ) != 0
		    || pthread_setcanceltype( PTHREAD_CANCEL_ENABLE,   &oldStat ) != 0 )
		{
			cout << "can't enable cancelling" << endl;
			return nullptr;
		}
		destr d;
		sleep( numeric_limits<int>::max() );
		return nullptr;
	};
	pthread_t pt;
	if( pthread_create( &pt, nullptr, thr, nullptr ) != 0 )
	{
		cout << "can't create thread" << endl;
		return -1;
	}
	if( pthread_cancel( pt ) != 0 )
	{
		cout << "can't cancel thread" << endl;
		return -1;
	}
	if( pthread_join( pt, nullptr ) != 0 )
	{
		cout << "can't join thread" << endl;
		return -1;
	}

}

Remember that a cancellation-request remains queued even if cancellation
isn't enabled yet.

[toc] | [prev] | [next] | [standalone]


#79838

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-28 05:27 +0200
Message-ID<s8pnuo$peb$3@dont-email.me>
In reply to#79835
>          if(    pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, &oldStat 
> ) != 0
>              || pthread_setcanceltype( PTHREAD_CANCEL_ENABLE,   &oldStat 
> ) != 0 )

Oh, a little bug:
		if(    pthread_setcanceltype(  PTHREAD_CANCEL_DEFERRED, &oldStat ) != 0
		    || pthread_setcancelstate( PTHREAD_CANCEL_ENABLE,   &oldStat ) != 0 )
But doesn't change anything.

[toc] | [prev] | [next] | [standalone]


#79837

FromIan Collins <ian-news@hotmail.com>
Date2021-05-28 14:59 +1200
Message-ID<ihb4kdFt2e6U1@mid.individual.net>
In reply to#79820
On 28/05/2021 12:52, Öö Tiib wrote:
> On Thursday, 27 May 2021 at 21:00:13 UTC+3, Chris Vine wrote:
>>
>> One other thing POSIX provides and C++11 doesn't is thread cancellation.
>> Some programmers who don't have relevant experience think thread
>> cancellation is a bad idea because it allows arbitrary cancellation
>> which cannot be adequately controlled (the "combing your hair with a
>> fork" jibe). Whilst that is true with windows it absolutely isn't with
>> POSIX. What you do is use deferred cancellation (the default in POSIX)
>> and block cancellation as normal policy, and only enable cancellation
>> at defined points in the code which are able to deal with it (normally
>> where a wait is to occur). Done properly, thread cancellation is far
>> easier to use than exceptions, which can jump out of anywhere if you
>> include std::bad_alloc in the mix. C++11 threads don't deal with
>> cancellation and will never be able to do so because they require OS
>> support - in this case POSIX support.
> 
> With that thread cancellation I'm always in doubt. Especially if discussed
> in context of RAII and destructor of thing like std::thread.
> 
> One of major reasons making a thread is to turn synchronous work into
> asynchronous. For that we put it into thread so then synchronous work is
> going on in thread doing its blocking operations (potentially checking if
> the work has become obsolete and/or reporting progress between those)
> and once complete (or failed) handing the results back over to caller thread.
> That way the caller thread has all benefits of asynchronous works going on.
> It is fully responsive, so can take care of other responsibilities, entertain
> users, report progresses, mark ongoing works obsolete and/or put out the
> results (or failures) once something becomes complete.
> 
> But what is that cancellation? It is like telling to worker thread to die in
> middle of unknown state potentially in kernel with unknown amount of
> locks taken, files open or mapped to virtual memory, that fragile external
> hardware device produced by random morons in middle of something
> and what not? std::terminate feels better and more honest than to cancel
> the thread ... at least our users will see that we screwed all up in major
> way. It all gets of course lost in examples because these talk about "foo()".

Cancellation is well defined in POSIX.  Cancellation points are defined 
by the standard and threads can manage their own cancellation type and 
state,

If you want to manage resources in a thread that may be cancelled, you 
can use cleanup functions.  I haven't tried it in Linux, but certainly 
in Solaris, the C++ runtime will destroy objects if the creating thread 
is cancelled.  This is one of those annoying behaviours not covered by 
either the C++ or POSIX standards...

A quick check on Linux shows that yes, destructors are called when a 
thread is cancelled.

-- 
Ian

[toc] | [prev] | [next] | [standalone]


#79839

FromÖö Tiib <ootiib@hot.ee>
Date2021-05-27 20:37 -0700
Message-ID<d106201a-aab3-4964-a415-5cc4dc7e482en@googlegroups.com>
In reply to#79837
On Friday, 28 May 2021 at 05:59:41 UTC+3, Ian Collins wrote:
> On 28/05/2021 12:52, Öö Tiib wrote: 
> > On Thursday, 27 May 2021 at 21:00:13 UTC+3, Chris Vine wrote: 
> >> 
> >> One other thing POSIX provides and C++11 doesn't is thread cancellation. 
> >> Some programmers who don't have relevant experience think thread 
> >> cancellation is a bad idea because it allows arbitrary cancellation 
> >> which cannot be adequately controlled (the "combing your hair with a 
> >> fork" jibe). Whilst that is true with windows it absolutely isn't with 
> >> POSIX. What you do is use deferred cancellation (the default in POSIX) 
> >> and block cancellation as normal policy, and only enable cancellation 
> >> at defined points in the code which are able to deal with it (normally 
> >> where a wait is to occur). Done properly, thread cancellation is far 
> >> easier to use than exceptions, which can jump out of anywhere if you 
> >> include std::bad_alloc in the mix. C++11 threads don't deal with 
> >> cancellation and will never be able to do so because they require OS 
> >> support - in this case POSIX support. 
> > 
> > With that thread cancellation I'm always in doubt. Especially if discussed 
> > in context of RAII and destructor of thing like std::thread. 
> > 
> > One of major reasons making a thread is to turn synchronous work into 
> > asynchronous. For that we put it into thread so then synchronous work is 
> > going on in thread doing its blocking operations (potentially checking if 
> > the work has become obsolete and/or reporting progress between those) 
> > and once complete (or failed) handing the results back over to caller thread. 
> > That way the caller thread has all benefits of asynchronous works going on. 
> > It is fully responsive, so can take care of other responsibilities, entertain 
> > users, report progresses, mark ongoing works obsolete and/or put out the 
> > results (or failures) once something becomes complete. 
> > 
> > But what is that cancellation? It is like telling to worker thread to die in 
> > middle of unknown state potentially in kernel with unknown amount of 
> > locks taken, files open or mapped to virtual memory, that fragile external 
> > hardware device produced by random morons in middle of something 
> > and what not? std::terminate feels better and more honest than to cancel 
> > the thread ... at least our users will see that we screwed all up in major 
> > way. It all gets of course lost in examples because these talk about "foo()".
> Cancellation is well defined in POSIX. Cancellation points are defined 
> by the standard and threads can manage their own cancellation type and 
> state, 
> 
> If you want to manage resources in a thread that may be cancelled, you 
> can use cleanup functions. I haven't tried it in Linux, but certainly 
> in Solaris, the C++ runtime will destroy objects if the creating thread 
> is cancelled. This is one of those annoying behaviours not covered by 
> either the C++ or POSIX standards... 
> 
> A quick check on Linux shows that yes, destructors are called when a 
> thread is cancelled. 

Very interesting ... but magical solutions make me even more worried.
Is there some kind of secret exception thrown or some kind of alternative
stack unwinding used or what? If secret exception then does 
catch(...) { mopup(); throw; } work or has it to be full RAII? If alternative
stack unwinding then what it costs and do noexcept(true) functions
in call stack compile still into that rainbow table because of it?

[toc] | [prev] | [next] | [standalone]


#79841

FromIan Collins <ian-news@hotmail.com>
Date2021-05-28 16:50 +1200
Message-ID<ihbb58Ft2e6U2@mid.individual.net>
In reply to#79839
On 28/05/2021 15:37, Öö Tiib wrote:
> On Friday, 28 May 2021 at 05:59:41 UTC+3, Ian Collins wrote:
>> On 28/05/2021 12:52, Öö Tiib wrote:
>>> On Thursday, 27 May 2021 at 21:00:13 UTC+3, Chris Vine wrote:
>>>>
>>>> One other thing POSIX provides and C++11 doesn't is thread cancellation.
>>>> Some programmers who don't have relevant experience think thread
>>>> cancellation is a bad idea because it allows arbitrary cancellation
>>>> which cannot be adequately controlled (the "combing your hair with a
>>>> fork" jibe). Whilst that is true with windows it absolutely isn't with
>>>> POSIX. What you do is use deferred cancellation (the default in POSIX)
>>>> and block cancellation as normal policy, and only enable cancellation
>>>> at defined points in the code which are able to deal with it (normally
>>>> where a wait is to occur). Done properly, thread cancellation is far
>>>> easier to use than exceptions, which can jump out of anywhere if you
>>>> include std::bad_alloc in the mix. C++11 threads don't deal with
>>>> cancellation and will never be able to do so because they require OS
>>>> support - in this case POSIX support.
>>>
>>> With that thread cancellation I'm always in doubt. Especially if discussed
>>> in context of RAII and destructor of thing like std::thread.
>>>
>>> One of major reasons making a thread is to turn synchronous work into
>>> asynchronous. For that we put it into thread so then synchronous work is
>>> going on in thread doing its blocking operations (potentially checking if
>>> the work has become obsolete and/or reporting progress between those)
>>> and once complete (or failed) handing the results back over to caller thread.
>>> That way the caller thread has all benefits of asynchronous works going on.
>>> It is fully responsive, so can take care of other responsibilities, entertain
>>> users, report progresses, mark ongoing works obsolete and/or put out the
>>> results (or failures) once something becomes complete.
>>>
>>> But what is that cancellation? It is like telling to worker thread to die in
>>> middle of unknown state potentially in kernel with unknown amount of
>>> locks taken, files open or mapped to virtual memory, that fragile external
>>> hardware device produced by random morons in middle of something
>>> and what not? std::terminate feels better and more honest than to cancel
>>> the thread ... at least our users will see that we screwed all up in major
>>> way. It all gets of course lost in examples because these talk about "foo()".
>> Cancellation is well defined in POSIX. Cancellation points are defined
>> by the standard and threads can manage their own cancellation type and
>> state,
>>
>> If you want to manage resources in a thread that may be cancelled, you
>> can use cleanup functions. I haven't tried it in Linux, but certainly
>> in Solaris, the C++ runtime will destroy objects if the creating thread
>> is cancelled. This is one of those annoying behaviours not covered by
>> either the C++ or POSIX standards...
>>
>> A quick check on Linux shows that yes, destructors are called when a
>> thread is cancelled.
> 
> Very interesting ... but magical solutions make me even more worried.
> Is there some kind of secret exception thrown or some kind of alternative
> stack unwinding used or what? If secret exception then does
> catch(...) { mopup(); throw; } work or has it to be full RAII? If alternative
> stack unwinding then what it costs and do noexcept(true) functions
> in call stack compile still into that rainbow table because of it?

I believe (at lease on Solaris), the "magic" is the runtime using 
pthread_cleanup_push/pthread_cleanup_pop to manage the destructor 
calling, there's no need for exceptions.  There's nothing to stop you 
doing this by hand...

There a a number of behaviours which fall between two standards and we 
have to rely on the quality of the implementation, this just happens to 
be one.

A simple test case:

#include <pthread.h>
#include <iostream>
#include <unistd.h>

struct foo
{
   foo() { std::cout << "constructor" << std::endl; }

   ~foo() { std::cout << "destructor" << std::endl; }
};

void*
thread(void*)
{
   foo f;

   while (true)
   {
     sleep(5);
   }

   return nullptr;
}


int
main()
{
   pthread_t t;

   pthread_create(&t, 0, thread, 0);

   sleep(1);
   pthread_cancel(t);

   pthread_join(t, 0);
}

-- 
Ian.

[toc] | [prev] | [next] | [standalone]


#79842

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-28 06:53 +0200
Message-ID<s8pt0k$esv$1@dont-email.me>
In reply to#79841
> A simple test case:
> 
> #include <pthread.h>
> #include <iostream>
> #include <unistd.h>
> 
> struct foo
> {
>    foo() { std::cout << "constructor" << std::endl; }
> 
>    ~foo() { std::cout << "destructor" << std::endl; }
> };
> 
> void*
> thread(void*)
> {
>    foo f;
> 
>    while (true)
>    {
>      sleep(5);
>    }
> 
>    return nullptr;
> }
> 
> 
> int
> main()
> {
>    pthread_t t;
> 
>    pthread_create(&t, 0, thread, 0);
> 
>    sleep(1);
>    pthread_cancel(t);
> 
>    pthread_join(t, 0);
> }

You have to makje the thread cancelable.

[toc] | [prev] | [next] | [standalone]


#79847

FromÖö Tiib <ootiib@hot.ee>
Date2021-05-27 23:07 -0700
Message-ID<ef425420-6a00-456d-bcc2-87f6851eae8dn@googlegroups.com>
In reply to#79841
On Friday, 28 May 2021 at 07:51:05 UTC+3, Ian Collins wrote:
> On 28/05/2021 15:37, Öö Tiib wrote: 
> > 
> > Very interesting ... but magical solutions make me even more worried. 
> > Is there some kind of secret exception thrown or some kind of alternative 
> > stack unwinding used or what? If secret exception then does 
> > catch(...) { mopup(); throw; } work or has it to be full RAII? If alternative 
> > stack unwinding then what it costs and do noexcept(true) functions 
> > in call stack compile still into that rainbow table because of it?
> 
> I believe (at lease on Solaris), the "magic" is the runtime using 
> pthread_cleanup_push/pthread_cleanup_pop to manage the destructor 
> calling, there's no need for exceptions. There's nothing to stop you 
> doing this by hand... 
> 
> There a a number of behaviours which fall between two standards and we 
> have to rely on the quality of the implementation, this just happens to 
> be one. 

My threads typically do some sequential work that can be time consuming
and complex (or otherwise why thread?). So I am unsure how to unit or
automatic test canceling it cheaply enough as magic goes in the
supernatural realm.

When I do by hand, set some atomic flag (that thread checks if it
should stop) and then join then I can measure, can mock that flag
checking function. It is lot easier?  

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web