Thread overview
dont understand this
Sep 24, 2016
collerblade
Sep 24, 2016
rikki cattermole
Sep 25, 2016
Meta
Sep 25, 2016
collerblade
Sep 25, 2016
collerblade
Sep 25, 2016
collerblade
September 24, 2016
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
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
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
> 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
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
> 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
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