Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
September 24, 2016 dont understand this | ||||
---|---|---|---|---|
| ||||
fellow D programmers I would like to ask a question! I would like to create a class, which works in a separated thread, while the class exisit. This is important. I want to kill/terminate/stop the third whenn the class get cleared. Thas what i got so far. This is what i got so far (very easy solution): class MyClass { public: this() { Thread thread=new Thread(&threadFunc); running=true; thread.start(); } ~this() { writeln(someVariable); running=false; } private: bool running=false; int someVariable=1; void threadFunc() { while(running) { someVariable++; } } } Becouse core.thread.Thread doesnt have any stop,pause,therminate method i have to stop the thread by myself (with the help of the running variable). The problem is: this ISNT WORKING. The reason is: the destructor never gets called, so the thread runs forever (application didnt exit). So the GC finds somewhere a pointer to the class's instance memory (which is ok i think, becouse i use delegate to create the thread). But imagagine this: when i change the running variable to static, everything works as expected, and the app frees and closes normally. Why is the running variable is different from the other someVariable?? Before u ask: - "shared bool running" doesnt works, only static. - Tried to keep a reference of the Thread as a local variable, result is the same - i tried 1000 times the code on 2 different PC, result is the same (no random pointer somewhere) - i use latest LDC Obviously, i want to avoid a static running variable, my class can have multiple instances. Ty Collerblade |
September 25, 2016 Re: dont understand this | ||||
---|---|---|---|---|
| ||||
Posted in reply to collerblade | On 25/09/2016 10:24 AM, collerblade wrote:
> fellow D programmers
>
> I would like to ask a question! I would like to create a class, which
> works in a separated thread, while the class exisit. This is important.
> I want to kill/terminate/stop the third whenn the class get cleared.
> Thas what i got so far. This is what i got so far (very easy solution):
>
> class MyClass {
> public:
> this() {
> Thread thread=new Thread(&threadFunc);
> running=true;
> thread.start();
> }
>
> ~this() {
> writeln(someVariable);
> running=false;
> }
>
> private:
> bool running=false;
> int someVariable=1;
>
> void threadFunc() {
> while(running) {
> someVariable++;
> }
> }
> }
>
> Becouse core.thread.Thread doesnt have any stop,pause,therminate method
> i have to stop the thread by myself (with the help of the running
> variable). The problem is: this ISNT WORKING. The reason is: the
> destructor never gets called, so the thread runs forever (application
> didnt exit). So the GC finds somewhere a pointer to the class's instance
> memory (which is ok i think, becouse i use delegate to create the thread).
> But imagagine this: when i change the running variable to static,
> everything works as expected, and the app frees and closes normally. Why
> is the running variable is different from the other someVariable??
> Before u ask:
> - "shared bool running" doesnt works, only static.
> - Tried to keep a reference of the Thread as a local variable, result is
> the same
> - i tried 1000 times the code on 2 different PC, result is the same (no
> random pointer somewhere)
> - i use latest LDC
>
> Obviously, i want to avoid a static running variable, my class can have
> multiple instances.
>
> Ty Collerblade
threadFunc contains a reference to MyClass in the form of the 'this' pointer and so the GC sees this and never deallocates the MyClass instance to begin with.
|
September 25, 2016 Re: dont understand this | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Saturday, 24 September 2016 at 21:56:38 UTC, rikki cattermole wrote:
> threadFunc contains a reference to MyClass in the form of the 'this' pointer and so the GC sees this and never deallocates the MyClass instance to begin with.
Not to mention that destructors are not guaranteed to ever be called for classes and heap-allocated structs.
|
September 25, 2016 Re: dont understand this | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | > threadFunc contains a reference to MyClass in the form of the 'this' pointer and so the GC sees this and never deallocates the MyClass instance to begin with.
Yes i am a ware about that fact, but when i set "running" to static, the solution WORKS. That is what the question is.
|
September 25, 2016 Re: dont understand this | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Sunday, 25 September 2016 at 04:25:59 UTC, Meta wrote:
> On Saturday, 24 September 2016 at 21:56:38 UTC, rikki cattermole wrote:
>> threadFunc contains a reference to MyClass in the form of the 'this' pointer and so the GC sees this and never deallocates the MyClass instance to begin with.
>
> Not to mention that destructors are not guaranteed to ever be called for classes and heap-allocated structs.
Do i have to do a stop() function myself?
|
September 25, 2016 Re: dont understand this | ||||
---|---|---|---|---|
| ||||
Posted in reply to collerblade | > Do i have to do a stop() function myself?
Ok i did a stop() function and i called when my class is not needed any more. But guess what: It doesnt stops the thread. My head is starts to blow up.
class ReplicatorServer: Replicator {
public:
this() {
Thread thread=new Thread(&threadFunc);
running=true;
thread.start();
}
void stop() {
running=false;
writeln("STOPPED");
}
private:
bool running=false;
int someVariable=1;
void threadFunc() {
while(running) {
someVariable++;
//Thread.yield();
}
}
}
Is threre something i dont understand with the concept here?? Becouse when i call Thread.yield() (in the threadFunc) repeatly, the class exists as normal.
Is running a thread local variable (their address is the same..)
|
September 27, 2016 Re: dont understand this | ||||
---|---|---|---|---|
| ||||
Posted in reply to collerblade | On 9/25/16 1:48 AM, collerblade wrote:
>> threadFunc contains a reference to MyClass in the form of the 'this'
>> pointer and so the GC sees this and never deallocates the MyClass
>> instance to begin with.
>
> Yes i am a ware about that fact, but when i set "running" to static, the
> solution WORKS. That is what the question is.
There is a misunderstanding here. It works because a static variable is *NOT* shared between threads.
i.e., make running static, then remove the set to false in the destructor, and you still will have the thread exit.
You cannot make a thread function that uses a delegate of a thread, which contains a pointer to that thread, and then expect the GC to kill the thread.
I know what you are trying to do, but I don't think you can do it with D's Thread objects. What you want to do is use a reference counter, and run the thread as long as the reference count is greater than 1. Then store your state in that object.
You can probably learn how to do this by reading the code for std.typecons.RefCounted.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation