Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
December 02, 2005 thread destruction | ||||
---|---|---|---|---|
| ||||
Using the following program ... ================= import std.thread; import std.stdio; import std.c.windows.windows; class athread : Thread { this () { super(&thread_main); writefln("create thread"); } ~this() { writefln("destroy thread"); } int thread_main () { Sleep(500); return 0; } } int main (char[][] args) { athread m0 = new athread; m0.start(); if(args.length > 1) { while (m0.getState == Thread.TS.RUNNING){} m0.wait(); if(args.length > 2) writefln("done"); } else { m0.wait(); } return 0; } ================= and running it thus ... ========================= c:\temp>build test4 Path and Version : D:\UTIL\build.exe v2.9(1197) built on Wed Aug 10 11:03:42 2005 f:\dmd\bin\..\..\dm\bin\link.exe test4,test4.exe,,user32+kernel32,test4.def/noi; c:\temp>test4 create thread destroy thread c:\temp>test4 1 create thread c:\temp>test4 1 2 create thread done destroy thread c:\temp> ========================= it would appear that the thread destructor doesn't get called if I wait on its state before finishing the program, *unless* I also call writefln(). -- Derek Parnell Melbourne, Australia 3/12/2005 9:27:00 AM |
December 02, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > Using the following program ... ... > it would appear that the thread destructor doesn't get called if I wait on > its state before finishing the program, *unless* I also call writefln(). Thread objects are not deleted explicitly when they terminate as something may have a reference to them. Instead, they're garbage collected like everything else. Have you tried adding a call to fullCollect() before exiting main? Sean |
December 03, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Fri, 02 Dec 2005 14:35:17 -0800, Sean Kelly wrote: > Derek Parnell wrote: >> Using the following program ... > ... >> it would appear that the thread destructor doesn't get called if I wait on its state before finishing the program, *unless* I also call writefln(). > > Thread objects are not deleted explicitly when they terminate as something may have a reference to them. Instead, they're garbage collected like everything else. Have you tried adding a call to fullCollect() before exiting main? Maybe I didn't make it clear enough. Sometimes their destructor is called when the program exits and sometimes they are not. It all depends on two things: (1) The destructor is called when the program exits, if I *DO NOT* use the getState() call. (2) The destructor is called when the program exits, if I *DO* use the getState() call but only if I also call writefln(). -- Derek Parnell Melbourne, Australia 3/12/2005 4:36:43 PM |
December 03, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> On Fri, 02 Dec 2005 14:35:17 -0800, Sean Kelly wrote:
>
>> Derek Parnell wrote:
>>> Using the following program ...
>> ...
>>> it would appear that the thread destructor doesn't get called if I wait on its state before finishing the program, *unless* I also call writefln().
>>
>> Thread objects are not deleted explicitly when they terminate as something may have a reference to them. Instead, they're garbage collected like everything else. Have you tried adding a call to fullCollect() before exiting main?
>
> Maybe I didn't make it clear enough. Sometimes their destructor is called when the program exits and sometimes they are not. It all depends on two things:
>
> (1) The destructor is called when the program exits, if I *DO NOT* use the
> getState() call.
>
> (2) The destructor is called when the program exits, if I *DO* use the
> getState() call but only if I also call writefln().
>
So? It's irrelevant. There is no guarantee that a destructor will or will not be called, since there's no guarantee that a class will or will not be collected. You may find the behavior of the GC to be a little unusual, but as far as I can tell, it's behaving to spec. I'll admit, however, that this GC behavior sounds a little weird. getState() must to something more than just return a value.
~John Demme
|
December 03, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Demme | On Sat, 03 Dec 2005 03:45:02 -0500, John Demme wrote: > Derek Parnell wrote: > >> On Fri, 02 Dec 2005 14:35:17 -0800, Sean Kelly wrote: >> >>> Derek Parnell wrote: >>>> Using the following program ... >>> ... >>>> it would appear that the thread destructor doesn't get called if I wait on its state before finishing the program, *unless* I also call writefln(). >>> >>> Thread objects are not deleted explicitly when they terminate as something may have a reference to them. Instead, they're garbage collected like everything else. Have you tried adding a call to fullCollect() before exiting main? >> >> Maybe I didn't make it clear enough. Sometimes their destructor is called when the program exits and sometimes they are not. It all depends on two things: >> >> (1) The destructor is called when the program exits, if I *DO NOT* use the >> getState() call. >> >> (2) The destructor is called when the program exits, if I *DO* use the >> getState() call but only if I also call writefln(). >> > > So? It's irrelevant. That depends on whether this behaviour is according to the specification or not. > There is no guarantee that a destructor will or will > not be called, since there's no guarantee that a class will or will not be > collected. Are you saying that the official specification states that when a program completes, i.e. main() exits, that D may *or* may not call the class' destructor function? > You may find the behavior of the GC to be a little unusual, but as far as I can tell, it's behaving to spec. If this is so, does it mean that D recommends that for every class instance that is constructed, the coder needs to explicitly call its destructor because D might not get around to it? BTW, I notice that even 'auto' fails in this instance too. I can understand that this behaviour for some types of resources held by an object, such as RAM, GDI handles, file handles, ... would be okay because the operating system takes responsibility in cleaning these up. But there are other types of resources that the operating system doesn't know about, such as database locking, transaction back-outs, remote servers, ... This behaviour will be the cause of many calls to a help desk in future. > I'll admit, however, that > this GC behavior sounds a little weird. getState() must to something more > than just return a value. ... but it doesn't ... weird, as you say. And why would calling writefln() affect it? -- Derek Parnell Melbourne, Australia 4/12/2005 9:19:40 AM |
December 07, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | "Derek Parnell" <derek@psych.ward> wrote in message news:1qadhbehg1olk$.zlet5a2vr2zj$.dlg@40tude.net... > ... but it doesn't ... weird, as you say. And why would calling writefln() > affect it? writefln() affects what is on the stack. The GC is conservative; if something looks like a reference to the data, the data is not free'd. The general rule with destructors is that they are only guaranteed to be called for: 1) auto objects 2) when an explicit 'delete' is called on it |
December 07, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Tue, 6 Dec 2005 20:13:03 -0800, Walter Bright wrote: > "Derek Parnell" <derek@psych.ward> wrote in message news:1qadhbehg1olk$.zlet5a2vr2zj$.dlg@40tude.net... >> ... but it doesn't ... weird, as you say. And why would calling writefln() >> affect it? > > writefln() affects what is on the stack. The GC is conservative; if something looks like a reference to the data, the data is not free'd. > > The general rule with destructors is that they are only guaranteed to be called for: > > 1) auto objects > 2) when an explicit 'delete' is called on it Therefore, to be on the safe side, as we might know what resources an object might hold, we should *always* use either auto or explicit deletes. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 7/12/2005 4:06:05 PM |
December 07, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> On Tue, 6 Dec 2005 20:13:03 -0800, Walter Bright wrote:
>
>
>>"Derek Parnell" <derek@psych.ward> wrote in message
>>news:1qadhbehg1olk$.zlet5a2vr2zj$.dlg@40tude.net...
>>
>>>... but it doesn't ... weird, as you say. And why would calling writefln()
>>>affect it?
>>
>>writefln() affects what is on the stack. The GC is conservative; if
>>something looks like a reference to the data, the data is not free'd.
>>
>>The general rule with destructors is that they are only guaranteed to be
>>called for:
>>
>>1) auto objects
>>2) when an explicit 'delete' is called on it
>
>
> Therefore, to be on the safe side, as we might know what resources an
> object might hold, we should *always* use either auto or explicit deletes.
AFAIK, that applies to any garbage collection scheme. For example, .NET finalisers are not guaranteed to be called. It does leave me a bit baffled as to what purpose a finaliser can serve.
|
December 07, 2005 Re: thread destruction | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | Don Clugston wrote:
>
> AFAIK, that applies to any garbage collection scheme. For example, .NET finalisers are not guaranteed to be called. It does leave me a bit baffled as to what purpose a finaliser can serve.
Languages built with GC in mind are a bit better off because the GC can use type information to only scan pointers, rather than things that might be pointers. This reduces the number of dead objects over time, though some still occur.
Sean
|
Copyright © 1999-2021 by the D Language Foundation