wxThread Kill()

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

On some page about wxThread is said, that calling Delete is a graceful way to terminate the thread, but there seems still to be some diference between detached and joinable threads. Also that TestDestroy, I have to call is not complete clear for me.
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxThread Kill()

Post by Natulux »

If I understood you correctly, you want to have a second thread running, which should only be closed if your main programm is about to close.
So you need a detached wxThread, or else (in the case of joinable) your main thread would wait for your sub thread to complete, which is never going to happen (because of your while(1)).
Since your sub thread is not getting the call, that the app is about to close, I guess one option is to call Delete from the main thread before closing the app. You should be aware though, that whatever your sub thread was doing is now in an undefined state, because it couldn't exit on its own. If you had some sort of saving at the end, that might be skipped etc.

You could also use a thread safe boolean variable, which your main thread sets to true upon deletion and your sub thread checks at the end of each loop to terminate on its own, when it is convenient to you (main thread as to wait for termination, of course).
See the "thread" sample "bool m_cancelled" for that.

Best
Natu
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

Natulux wrote:If I understood you correctly, you want to have a second thread running, which should only be closed if your main programm is about to close.
So you need a detached wxThread, or else (in the case of joinable) your main thread would wait for your sub thread to complete, which is never going to happen (because of your while(1)).
Since your sub thread is not getting the call, that the app is about to close, I guess one option is to call Delete from the main thread before closing the app. You should be aware though, that whatever your sub thread was doing is now in an undefined state, because it couldn't exit on its own. If you had some sort of saving at the end, that might be skipped etc.

You could also use a thread safe boolean variable, which your main thread sets to true upon deletion and your sub thread checks at the end of each loop to terminate on its own, when it is convenient to you (main thread as to wait for termination, of course).
See the "thread" sample "bool m_cancelled" for that.

Best
Natu
Na I could change my while loop from while(1) to while(!TestDestroy()), would it be better? Also I think I need joinable Thread as I don´t want to use new. My background thread just should write some information to textfield of the frame, so it can´t run after the frame was deleted.
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxThread Kill()

Post by Natulux »

gtafan wrote:I could change my while loop from while(1) to while(!TestDestroy()), would it be better?
Yes, that would be better. TestDestroy() checks wheather Delete() Or Wait() has been called from your main thread, that is why Delete is able to termiante the thread gracefully.
gtafan wrote:Also I think I need joinable Thread as I don´t want to use new. My background thread just should write some information to textfield of the frame, so it can´t run after the frame was deleted.
You may have misunderstood the difference between joinable and detached threads.

https://docs.wxwidgets.org/3.1/classwx_thread.html
Conversely, joinable threads do not delete themselves when they are done processing and as such are safe to create on the stack. Joinable threads also provide the ability for one to get value it returned from Entry() through Wait().
But:
You shouldn't hurry to create all the threads joinable, however, because this has a disadvantage as well: you must Wait() for a joinable thread or the system resources used by it will never be freed, and you also must delete the corresponding wxThread object yourself if you did not create it on the stack. In contrast, detached threads are of the "fire-and-forget" kind: you only have to start a detached thread and it will terminate and destroy itself.
Usually, when I wanted to have a "background thread" doing something parallel to my main thread, I used a detached thread.
(like your case)
If I wanted to have some long and/or intensive work to be done, I use joinable worker threads, starting several of them to do something quick, I create them and than WAIT for them.
(eg. I once used Windows console commands on a whole network range. This took several seconds for each IP. But I could use worker threads to run several queries at once. I stored them in a vector and waited for each of them to finish).
Note, that this is not in the background anymore, because your main thread is waiting all the time!

For C++11 std::thread, the doc even sais it explicitly:
https://en.cppreference.com/w/cpp/thread/thread/join
Blocks the current thread until the thread identified by *this finishes its execution.
You might get around this with wxThread, but you are not supposed to.

My advice: Start a background thread as detached, make it TestDestroy (as you already have) and call Delete on it, just before exiting your main app.

Cheers
Natu
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxThread Kill()

Post by doublemax »

Also I think I need joinable Thread as I don´t want to use new.
There are very few situations where it makes sense to create a thread object on the stack, because it would be destroyed when it goes out of scope. In 99% of cases they should be created on the heap (= with new).

Apart from that: I would suggest to do what Natulux said.
Use the source, Luke!
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

My thread alocates no resorces, that should be freed and it make sence for the frame to wait for the thread to be terminated befor the frame is destoied. I was thinking to have something like that inside MyFrame class:

Code: Select all

MyThread thread;
then in the constructor of MyFrame I have to call:

Code: Select all

thread.Run();
and in destructor:

Code: Select all

thread.Delete();
the frame have to wait fot the thread to be deleted befor it deletes itself. Can it worck this way? The performance play not a big role.
Manolo
Can't get richer than this
Can't get richer than this
Posts: 827
Joined: Mon Apr 30, 2012 11:07 pm

Re: wxThread Kill()

Post by Manolo »

If you have only one joinable thread, and you must wait until it finishes, how is this different from not using threads at all?

IMHO, joinable threads may be useful if you fire several at once. I consider this case as a way to speed up tasks that can be parallelized, and the app can't continue until that task is done.

OTOH, using an only detached thread allows your app to respond to any user action, like pressing a button to ask for early finish the thread.
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

Manolo wrote:If you have only one joinable thread, and you must wait until it finishes, how is this different from not using threads at all?

IMHO, joinable threads may be useful if you fire several at once. I consider this case as a way to speed up tasks that can be parallelized, and the app can't continue until that task is done.

OTOH, using an only detached thread allows your app to respond to any user action, like pressing a button to ask for early finish the thread.
Posibly I misunderstood something, I need to wait for the thread only at the end the rest it should run in background parallel to the main thread.
However an other reason I want to use joinable threads, because I don´t have to use new and I really hate pointers. Or is there a way to have detached thread without using new?
Like I mentioned the thread does some calculations in background and writing the results to some textfield of the frame. The thread shouldn´t defenetly go out of scope befor the application is closed.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxThread Kill()

Post by ONEEYEMAN »

Hi,
Can you do the calculation on timer?
Or this calculation absolutely have to be done in background and your program will use the results of the calculation even in the middle of the processing?

Thank you.

P.S.:

What I mean is this:

Let's say you thread will add the number 2 to the parameter, like this:

void foo(int &x)
{
x += 2;
}

Then during you main thread (GUI) you do this:

while( !TestDestroy() )
{
int a = 0;
foo( a );
std::out << a << endl;
}

What I mean is - yopu continuosly using the calculation result independently whether it finished or not.

Is this the case?
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

ONEEYEMAN wrote:Hi,
Can you do the calculation on timer?
Or this calculation absolutely have to be done in background and your program will use the results of the calculation even in the middle of the processing?

Thank you.

P.S.:

What I mean is this:

Let's say you thread will add the number 2 to the parameter, like this:

void foo(int &x)
{
x += 2;
}

Then during you main thread (GUI) you do this:

while( !TestDestroy() )
{
int a = 0;
foo( a );
std::out << a << endl;
}

What I mean is - yopu continuosly using the calculation result independently whether it finished or not.

Is this the case?
The calculation itself is not really used by the main thread, the result must be displaied to the user. The only case when calculation result is of interest for the main thread is when an error ocures. I was also thinking to use Timer, but since networcking IO is involved in that calculation process it would unnecesary block the user input.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxThread Kill()

Post by ONEEYEMAN »

Hi,
So all in all the reason for MT is to not block UI for the time calculation is done?
How much time does it take to perform it?

Thank you.
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

ONEEYEMAN wrote:Hi,
So all in all the reason for MT is to not block UI for the time calculation is done?
How much time does it take to perform it?

Thank you.
I have done no performance tests, since it is not limited to some special PC. Also since results from background thread are not used by the main application itself, exept an error ocures, multithreading should be a good idea.
I mean every n ms some values should be requested from networck and calculations done with them shown to the user.
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxThread Kill()

Post by Natulux »

gtafan wrote:Posibly I misunderstood something, I need to wait for the thread only at the end the rest it should run in background parallel to the main thread.
Yes, that is what I tried to tell you with the examples I provided for you. You have to wait for your joined thread right after you ran it! (and not at the end of your app). A joined thread is not(!) designed to serve as a background process!
Is is named "joined thread" because the thread 'joins' with your main thread after it has finished the worker task. A 'detached thread' on the other hand "detaches" from your main thread to run along parallel.
gtafan wrote:However an other reason I want to use joinable threads, because I don´t have to use new and I really hate pointers. Or is there a way to have detached thread without using new?
Not that I know of. You see, that is how C++ works:
If you use variables or objects on the stack, then you use the very fast but sparse RAM memory. Because this should only be used temporarily, everything created on the stack is destroyed, as soon as your code runs out of its scope:

Code: Select all

//This is a scope, create on the stack
if(x)
{ //<- Beginn scope
	MyClass myObject;
} //<- End scope, myObject is destroyed
If you want your thread to exist parallel, you need to create it on the heap. Everything using "new" is created on the heap. Heap is a little slower, but you have plenty of memory:

Code: Select all

//Create on the heap
MyClass * myObject;
if(x)
{ //<- Beginn scope
	myObject = new MyClass ();
} //<- End scope, myObject IS NOT destroyed
wxDELETE(myObject); //now 'myObject' is beeing destroyed
This is a trivial example of course, and if you create your thread as a member variable of your app or frame, then it is in app or frame scope and will not be destroyed until the end.
BUT: The whole point is, that when using the 'new' operator, you can (and should) destroy your object whenever you please (using TestDestroy and Delete the way discussed before). If you created your thread on the stack (without 'new'), e.g. in the scope of your frame object, the frame destructor will automatically free the memory (destroy the thread) in the end. This is no gracefull termination (at least not to my knowledge) and will probably crash your app or most certainly leave your thread in undefined behavior. And you can't Delete() your thread if it is created on the stack, because if the destructor wants to destruct something that has been destroyed before, you again will receive most certainly an unhandled exception or app crash.
gtafan wrote:Like I mentioned the thread does some calculations in background and writing the results to some textfield of the frame. The thread shouldn´t defenetly go out of scope befor the application is closed.
If you really want to do it this way, you have to abandon your fear of using pointers. In C++ you can't yet get around them.

Please note that I am not an expert on this matter and if you are still not convinced to use 'new' or find a way to use a timer instead, please try your solution and see if you are satisfied with the way it works and the way your app closes. If so, you don't need to bother. I merely tried to tell you how it is supposed to work according to my knowledge and it should work, if you use the thread as described by us and the links.

But be aware, that even a working solution can result in undefined behavior later on, when you don't use the classes the way they were supposed to.

Best
Natu
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxThread Kill()

Post by ONEEYEMAN »

Hi,
Keep in mind though that everything Natu said is the basic C++ and have nothing to do with wxWidgets.
And if you dont understand all this - I suggest to go back to school and learn.

Thank you.
gtafan
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 201
Joined: Wed Mar 29, 2017 9:52 am

Re: wxThread Kill()

Post by gtafan »

Natulux wrote:
gtafan wrote:Posibly I misunderstood something, I need to wait for the thread only at the end the rest it should run in background parallel to the main thread.
Yes, that is what I tried to tell you with the examples I provided for you. You have to wait for your joined thread right after you ran it! (and not at the end of your app). A joined thread is not(!) designed to serve as a background process!
Is is named "joined thread" because the thread 'joins' with your main thread after it has finished the worker task. A 'detached thread' on the other hand "detaches" from your main thread to run along parallel.
gtafan wrote:However an other reason I want to use joinable threads, because I don´t have to use new and I really hate pointers. Or is there a way to have detached thread without using new?
Not that I know of. You see, that is how C++ works:
If you use variables or objects on the stack, then you use the very fast but sparse RAM memory. Because this should only be used temporarily, everything created on the stack is destroyed, as soon as your code runs out of its scope:

Code: Select all

//This is a scope, create on the stack
if(x)
{ //<- Beginn scope
	MyClass myObject;
} //<- End scope, myObject is destroyed
If you want your thread to exist parallel, you need to create it on the heap. Everything using "new" is created on the heap. Heap is a little slower, but you have plenty of memory:

Code: Select all

//Create on the heap
MyClass * myObject;
if(x)
{ //<- Beginn scope
	myObject = new MyClass ();
} //<- End scope, myObject IS NOT destroyed
wxDELETE(myObject); //now 'myObject' is beeing destroyed
This is a trivial example of course, and if you create your thread as a member variable of your app or frame, then it is in app or frame scope and will not be destroyed until the end.
BUT: The whole point is, that when using the 'new' operator, you can (and should) destroy your object whenever you please (using TestDestroy and Delete the way discussed before). If you created your thread on the stack (without 'new'), e.g. in the scope of your frame object, the frame destructor will automatically free the memory (destroy the thread) in the end. This is no gracefull termination (at least not to my knowledge) and will probably crash your app or most certainly leave your thread in undefined behavior. And you can't Delete() your thread if it is created on the stack, because if the destructor wants to destruct something that has been destroyed before, you again will receive most certainly an unhandled exception or app crash.
gtafan wrote:Like I mentioned the thread does some calculations in background and writing the results to some textfield of the frame. The thread shouldn´t defenetly go out of scope befor the application is closed.
If you really want to do it this way, you have to abandon your fear of using pointers. In C++ you can't yet get around them.

Please note that I am not an expert on this matter and if you are still not convinced to use 'new' or find a way to use a timer instead, please try your solution and see if you are satisfied with the way it works and the way your app closes. If so, you don't need to bother. I merely tried to tell you how it is supposed to work according to my knowledge and it should work, if you use the thread as described by us and the links.

But be aware, that even a working solution can result in undefined behavior later on, when you don't use the classes the way they were supposed to.

Best
Natu
I am not fearing pointers, but I hate to use them because they can produce memory leaks sometimes and they (memleaks) are really hard to find out. I personaly don´t see a reason why a detached thread always have to be deleted after it finished worck. I know this is not the right place to discus the implementation of threads, but C++ really has a strange way to do it.
Timer posibly could be a better solution, but it will block user interaction with the GUI.
However thanks a lot for your explanation, it was really helpfull.
Post Reply