|
|||
|
Hello.
I have read that some Windows API functions like ExitThread() do not call the destructors of classes. Is this true? Is then useless to follow the RAII principle when working with the Windows API? Are there "safer" versions of this function? { OS independant replies only please - mod} Thanks in advance, Camilo -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|
||||
|
||||
|
|
|
|||
|
On 10/15/2011 5:18 AM, Camilo Bravo Valdés wrote:
> Hello. > > I have read that some Windows API functions like ExitThread() do not > call the destructors of classes. Is this true? Is then useless to > follow the RAII principle when working with the Windows API? Are there > "safer" versions of this function? > { OS independant replies only please - mod} > I think this is common to all threading API's. C++11 may fix this, but if you're using an C++03 compiler, try defining a special exception, and catch it only in the top level thread function. The exception propagation will call your destructors and then when you exit the top level thread function, the thread will terminate. struct TerminateThread { int const exit_code; TerminateThread(int x) : exit_code(x) { } }; int thread_function() { try { // do stuff // exit normally } catch (TerminateThread e) { return e.exit_code; } } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
> I have read that some Windows API functions like ExitThread() do not
> call the destructors of classes. Is this true? That's what the documentation says. > Is then useless to > follow the RAII principle when working with the Windows API? Not at all. ExitThread and similar thread/process functions are really intended as a last resort, they are not the normal way of exiting a thread. Dave -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Oct 15, 2:18 pm, Camilo Bravo Valdés <kmilo.br...@gmail.com> wrote:
> Hello. > > I have read that some Windows API functions like ExitThread() do not > call the destructors of classes. Is this true? Is then useless to > follow the RAII principle when working with the Windows API? Are there > "safer" versions of this function? > { OS independant replies only please - mod} There are functions that do not return, like the one you mention. So, to enforce things like RAII, you simply must not use them. Note that RAII is but one example, as any locally-scoped resource might be in danger with such calls. That said... You might be trying to terminate a thread forcibly, from another thread. That's poor, poor programming practice, exactly for reason mentioned above: you lose control of any locally-scoped resources and possibly other things with thread affinity. Correct way to "terminate" a thread is to ask it to terminate and then wait for it. Thread code itself, must be aware that it can be asked to stop at any given moment, and it has to be written to be able to do so. Best practical way to do this is to: * create a particular exception type (e.g. your own class). Possibly hide it from thread code so that it can't possibly catch it, because it shouldn't ever do that. * expose something like check_termination function to thread code * call said function from various places in thread code so that thread can terminate in a timely fashion. The above is about the only correct manner, ever, to "terminate" a thread in general. Anything else can be done just under massive constraints on what thread code does. Goran. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Mon, 17 Oct 2011 14:48:50 -0700 (PDT)
Goran <goran.pusic@gmail.com> wrote: > There are functions that do not return, like the one you mention. So, > to enforce things like RAII, you simply must not use them. Note that > RAII is but one example, as any locally-scoped resource might be in > danger with such calls. > > That said... You might be trying to terminate a thread forcibly, from > another thread. That's poor, poor programming practice, exactly for > reason mentioned above: you lose control of any locally-scoped > resources and possibly other things with thread affinity. Correct way > to "terminate" a thread is to ask it to terminate and then wait for > it. As it happens C++11 came close to including provision for thread interruption; but because either cancellation or your "suicide request" approach requires blocking system calls to be interrupted in some way in order to be fully effective, any complete system is intrinsically non-portable. More generally, I think you are making too broad a statement, as either approach (cancellation or suicide request) depends on the implementation and in particular the platform. All modern commercial unixes and most recent BSDs/linuxes will unwind the stack on deferred cancellation by means of a pseudo-exception when run under a C++ environment, and this is a good language fit. With appropriate setting of thread cancellation status (so the thread receiving the cancellation request can nominate its own cancellation points) it is indistinguishable in effect from finding a way to request the receiving thread to terminate itself and throw its own exception. However, as I said, this is OS dependent. Getting a blocking system call to unblock on cancellation or "finding a way to request the receiving thread to terminate itself" when in a blocking call (say by a signal), which is essential to many real-life use cases, is considerably easier under unix-like OSes. Indeed windows never used to offer deferred cancellation at all (I don't know if it does now). Chris -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Oct 18, 9:46 pm, Chris Vine <ch...@cvine--nospam--.freeserve.co.uk>
wrote: > On Mon, 17 Oct 2011 14:48:50 -0700 (PDT) > > Goran <goran.pu...@gmail.com> wrote: > > There are functions that do not return, like the one you mention. So, > > to enforce things like RAII, you simply must not use them. Note that > > RAII is but one example, as any locally-scoped resource might be in > > danger with such calls. > > > That said... You might be trying to terminate a thread forcibly, from > > another thread. That's poor, poor programming practice, exactly for > > reason mentioned above: you lose control of any locally-scoped > > resources and possibly other things with thread affinity. Correct way > > to "terminate" a thread is to ask it to terminate and then wait for > > it. > > As it happens C++11 came close to including provision for thread > interruption; but because either cancellation or your "suicide > request" approach requires blocking system calls to be interrupted in > some way in order to be fully effective, any complete system is > intrinsically non-portable. I agree. I am pretty certain that in a "real-world" codebase there's going to be many blocking calls with no means of interrupting them, system or otherwise, and that someone has to write some code for those to either not take too long, either to become interruptible. BTW, what do you mean by "C++11 came close to..."? I took a brief look at std::thread, I see nothing on the line of interruption... > More generally, I think you are making too broad a statement, as either > approach (cancellation or suicide request) depends on the implementation > and in particular the platform. All modern commercial unixes and most > recent BSDs/linuxes will unwind the stack on deferred cancellation by > means of a pseudo-exception when run under a C++ environment, and this > is a good language fit. With appropriate setting of thread > cancellation status (so the thread receiving the cancellation request > can nominate its own cancellation points) it is indistinguishable in > effect from finding a way to request the receiving thread to terminate > itself and throw its own exception. > > However, as I said, this is OS dependent. Getting a blocking system call > to unblock on cancellation or "finding a way to request the receiving > thread to terminate itself" when in a blocking call (say by a signal), > which is essential to many real-life use cases, is considerably easier > under unix-like OSes. Indeed windows never used to offer deferred > cancellation at all (I don't know if it does now). On windows, I've been using so-called overlapped I/O, with waiting on both I/O and a "cancellation" event with some success ;-). Goran. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
On Wed, 19 Oct 2011 06:00:23 -0700 (PDT)
Goran <goran.pusic@gmail.com> wrote: > On Oct 18, 9:46 pm, Chris Vine <ch...@cvine--nospam--.freeserve.co.uk> > wrote: [snip] > > As it happens C++11 came close to including provision for thread > > interruption; but because either cancellation or your "suicide > > request" approach requires blocking system calls to be interrupted > > in some way in order to be fully effective, any complete system is > > intrinsically non-portable. > > I agree. I am pretty certain that in a "real-world" codebase there's > going to be many blocking calls with no means of interrupting them, > system or otherwise, and that someone has to write some code for those > to either not take too long, either to become interruptible. BTW, what > do you mean by "C++11 came close to..."? I took a brief look at > std::thread, I see nothing on the line of interruption... There is probably a language issue here, but I said "came close to including" not "does include". You can look at the WG21 working papers if you want to read more about it. If you want to examine what form it might have taken, see boost's thread interruption and some of the early WG21 papers based on it. On blocking system calls as cancellation points, this is already completely specified on POSIX platforms and doesn't need anyone to write anything: in effect all blocking system calls are made cancellation points unless the receiving thread has set itself to refuse deferred cancellation requests at that point. (If the moderator permits it, this is in System Interfaces, section 2.9.2, Cancellation Points, of the SUS: if not, moderator please remove these words in perenthesis, but I think the reference is of use in this discussion by demonstrating the inherent non-portability of thread cancellation). If you want to write cancellable code you must write it with cancellation in mind, just as if you want to write thread safe code you must write it with thread safety in mind. Or if you want to write exception safe code, you must write it with exceptions in mind. If that was your main point, then I agree. Chris -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|