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.
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 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 see your point and I hate memory leaks, too. In this case though, you are quite safe because you delete your pointer only once and only upon ending the whole program. Memory leaks usually are only a problem, when they happen in a loop during app runtime.
Even if you created a memory leak in the end, your app is about to destroy anyway, so - no need to worry.
gtafan wrote: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.
The "detached" thread does not need to be destroyed (after it finished), but the joined thread does. Was that maybe what you meant? :wink:
gtafan wrote: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.
When using a timer, it kind of feels like it was in another thread, but when the timer executes its timer function, this is queued in into the main event loop and eventually pauses your main thread for the time it needs to compute. If your function doesn't need a whole lot of time, you shouldn't experience this as "gui blocking" though. If it does indeed need a whole lot of time, you actually need multi threading or multi processing to keep it running fluently. But if you think threads to be inconvenient, I can't really recommend multi processing either (using wxProcess (wxExecute) and another exe to compute and you would need to exchange data between those - with e.g. wxSocketServer ... ).

You could also have a look at C++11 std::thread or boost::thread but to my knowledge they behave the same regarding "joined" and "detached".

All the 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:
gtafan wrote: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 see your point and I hate memory leaks, too. In this case though, you are quite safe because you delete your pointer only once and only upon ending the whole program. Memory leaks usually are only a problem, when they happen in a loop during app runtime.
Even if you created a memory leak in the end, your app is about to destroy anyway, so - no need to worry.
gtafan wrote: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.
The "detached" thread does not need to be destroyed (after it finished), but the joined thread does. Was that maybe what you meant? :wink:
gtafan wrote: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.
When using a timer, it kind of feels like it was in another thread, but when the timer executes its timer function, this is queued in into the main event loop and eventually pauses your main thread for the time it needs to compute. If your function doesn't need a whole lot of time, you shouldn't experience this as "gui blocking" though. If it does indeed need a whole lot of time, you actually need multi threading or multi processing to keep it running fluently. But if you think threads to be inconvenient, I can't really recommend multi processing either (using wxProcess (wxExecute) and another exe to compute and you would need to exchange data between those - with e.g. wxSocketServer ... ).

You could also have a look at C++11 std::thread or boost::thread but to my knowledge they behave the same regarding "joined" and "detached".

All the best
Natu
Geting data from networck and do some calculations with it can take some time, so it could block user interaction, but on another hand I noticed that in some places the main thread and the background one need to be syncronized which could have a similar effect. So posibly timer is a better solution?
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 »

Looks like the timer is not a perfect solution. I tried it, but in some situations it seems to behave like unsynchronized thread.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxThread Kill()

Post by doublemax »

Can you explain in more detail what you want to achieve?

Especially: While the background thread is working, can the user continue to use the application in every way?
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 »

doublemax wrote:Can you explain in more detail what you want to achieve?

Especially: While the background thread is working, can the user continue to use the application in every way?
Since the background thread is working all the time the main thread exists, the user should still be able to use the application in every way. The background thread should just actualize some data from networck by doing some calculations with it.
However looks like detached thread can do the worck better, just need to synchronize the networck acces with a mutex. The explanation by Natulux was really helpfull.
The only thing I am not really understanding is about that events a background thread can send to the main application.
An other problem I noticed, after calling Delete() on the background thread, the main thread is not waiting untill it really deleted, but it needs to do so.
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:Looks like the timer is not a perfect solution. I tried it, but in some situations it seems to behave like unsynchronized thread.
gtafan wrote:Since the background thread is working all the time the main thread exists, the user should still be able to use the application in every way. The background thread should just actualize some data from networck by doing some calculations with it.
If a timer can behave like an "unsynchronized thread" then there has to be some direct interaction between your two threads. Hence the question, if your main app is dependend on the results of the second one, or if it stays fully interactive all the time.
To my understanding, the user is giving parameters with the main app gui and the second thread/timer is using some network data + gui data to calculate and show something? In that case, no matter what you enter in your gui, every now and then the calculation should update or, as you said, "synchronize".
If your main thread "gui" app is dependent on that calculations of the second thread and therefore waits for the results of it, it's a different scenario.
gtafan wrote:The only thing I am not really understanding is about that events a background thread can send to the main application.
When using a timer, that timer is sending events to your main event loop and in that event function, you may do your calculations. When using a timer, your main thread should never pause (sleep, MessageBox or similar), or the handling of the event loop will be paused, too.
If you actually meant an event, ommited by your second thread, which should be handled by your main thread, im not sure what you are reffering to or why you would want to do that.
gtafan wrote:An other problem I noticed, after calling Delete() on the background thread, the main thread is not waiting untill it really deleted, but it needs to do so.
Looking into the docs, i find:
Calling Delete() gracefully terminates a detached thread, either when the thread calls TestDestroy() or when it finishes processing.
And diving into that, https://docs.wxwidgets.org/3.1/classwx_ ... d_deletion:
Regardless of whether it has terminated or not, you should call Wait() on a joinable thread to release its memory, as outlined in Types of wxThreads. If you created a joinable thread on the heap, remember to delete it manually with the delete operator or similar means as only detached threads handle this type of memory management.

Since detached threads delete themselves when they are finished processing, you should take care when calling a routine on one. If you are certain the thread is still running and would like to end it, you may call Delete() to gracefully end it (which implies that the thread will be deleted after that call to Delete()). It should be implied that you should never attempt to delete a detached thread with the delete operator or similar means.

As mentioned, Wait() or Delete() functions attempt to gracefully terminate a joinable and a detached thread, respectively. They do this by waiting until the thread in question calls TestDestroy() or ends processing (i.e. returns from wxThread::Entry).

Obviously, if the thread does call TestDestroy() and does not end, the thread which called Wait() or Delete() will come to halt. This is why it's important to call TestDestroy() in the Entry() routine of your threads as often as possible and immediately exit when it returns true.

As a last resort you can end the thread immediately through Kill(). It is strongly recommended that you do not do this, however, as it does not free the resources associated with the object (although the wxThread object of detached threads will still be deleted) and could leave the C runtime library in an undefined state.
So, are you sure, you call periodically TestDestroy() in your second thread?
Delete does give you a return value (wxThreadError), which should be wxTHREAD_NO_ERROR (==0). If it is greater 0, you can evaluate your error by checking the output (https://docs.wxwidgets.org/3.1/interfac ... 3035f75ac2):
enum wxThreadError:

wxTHREAD_NO_ERROR
No error.

wxTHREAD_NO_RESOURCE
No resource left to create a new thread.

wxTHREAD_RUNNING
The thread is already running.

wxTHREAD_NOT_RUNNING
The thread isn't running.

wxTHREAD_KILLED
Thread we waited for had to be killed.

wxTHREAD_MISC_ERROR
Some other error.
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 »

I am calling TestDestroy() and the thread terminates, but the main thread is not waiting for it to terminate.
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 »

This shouldn't be necessary or might even be wrong, but maybe try and call "Wait()" on the thread, after calling "Delete".

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

Re: wxThread Kill()

Post by doublemax »

You can only Wait() for joined threads. Detached threads are "fire and forget" as they destroy themselves.

You can:

1) just ignore it and terminate the application after calling Destroy() (not recommended)

2) wait a fixed amount of time (e.g. 1 second) after calling Destroy(). If the thread calls TestDestroy() often enough, that should be enough for it to terminate gracefully (not ideal, but still better than 1) )

3) implement some kind of functionality that enables you to wait for the detached thread. The sample code in the wxThread documentation shows one way to do it: https://docs.wxwidgets.org/trunk/classwx_thread.html
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 »

doublemax wrote:You can only Wait() for joined threads. Detached threads are "fire and forget" as they destroy themselves.

You can:

1) just ignore it and terminate the application after calling Destroy() (not recommended)

2) wait a fixed amount of time (e.g. 1 second) after calling Destroy(). If the thread calls TestDestroy() often enough, that should be enough for it to terminate gracefully (not ideal, but still better than 1) )

3) implement some kind of functionality that enables you to wait for the detached thread. The sample code in the wxThread documentation shows one way to do it: https://docs.wxwidgets.org/trunk/classwx_thread.html
Using an endless loop to wait for the end of thread and after that leaving it with breack is a really ugly solution in my opinion. I mean while(m_pThread); would be a bit better, but still a waste of resorces. I thought Delete waits for thread to call TestDestroy() and only after that the main application goes on.
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:Using an endless loop to wait for the end of thread and after that leaving it with breack is a really ugly solution in my opinion. I mean while(m_pThread); would be a bit better, but still a waste of resorces. I thought Delete waits for thread to call TestDestroy() and only after that the main application goes on.
Since Delete returns a flag of success, I thought so, too. It can't return any state of success, if it doesn't wait and check if it was successfull.

But it's not that hard to make it wait manually. Make the threads share a mutex protected (threadsafe) boolean, which you set to true in your second thread when you are done and you wait for that bool in your main thread.
You can make it timeout quite easily by using wxStopWatch (untested code):

Code: Select all

second_thread->Delete();
wxStopWatch sw;
while(!mutex_protected_boolean && sw.Time() < 3000)
{
	Sleep(50);
}
But place the declaration of this boolean in your main thread, or it is destructed to early!

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

Re: wxThread Kill()

Post by doublemax »

I mean while(m_pThread); would be a bit better, but still a waste of resorces.
When it happens at the end of the program, it's not a big deal.
I thought Delete waits for thread to call TestDestroy() and only after that the main application goes on.
The only difference would be that the wait happens inside the wxThread code and not in your code.
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 »

Natulux wrote:
gtafan wrote:Using an endless loop to wait for the end of thread and after that leaving it with breack is a really ugly solution in my opinion. I mean while(m_pThread); would be a bit better, but still a waste of resorces. I thought Delete waits for thread to call TestDestroy() and only after that the main application goes on.
Since Delete returns a flag of success, I thought so, too. It can't return any state of success, if it doesn't wait and check if it was successfull.

But it's not that hard to make it wait manually. Make the threads share a mutex protected (threadsafe) boolean, which you set to true in your second thread when you are done and you wait for that bool in your main thread.
You can make it timeout quite easily by using wxStopWatch (untested code):

Code: Select all

second_thread->Delete();
wxStopWatch sw;
while(!mutex_protected_boolean && sw.Time() < 3000)
{
	Sleep(50);
}
But place the declaration of this boolean in your main thread, or it is destructed to early!

Best
Natu
But that´s still buisy waiting. I mean it´s defenetly better then endles loop, but I am wondering why there is no good mechanism in C++ to manage something like that. I mean in Java something like that could be done very easy.
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:But that´s still buisy waiting. I mean it´s defenetly better then endles loop, but I am wondering why there is no good mechanism in C++ to manage something like that. I mean in Java something like that could be done very easy.
Well, as DoubleMax already said: At some point the code is waiting, in the main thread or in the second thread - the result would be the same. At least you have full control over the waiting process, when you do it yourself. ;-)

Mind you, this is not pure C++, it is wxWidgets Framework and wxThread is quite a bit older than std::thread of C++11 (which came quite late in comparison to other languages).

But when working with open source frameworks, you have to accept when some things are not always up to date. And you can make the decision yourself, if you want to use the new C++ standards or stick to your framework. It doesn't hurt to mix in the strong sides of both, though.

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:
gtafan wrote:But that´s still buisy waiting. I mean it´s defenetly better then endles loop, but I am wondering why there is no good mechanism in C++ to manage something like that. I mean in Java something like that could be done very easy.
Well, as DoubleMax already said: At some point the code is waiting, in the main thread or in the second thread - the result would be the same. At least you have full control over the waiting process, when you do it yourself. ;-)

Mind you, this is not pure C++, it is wxWidgets Framework and wxThread is quite a bit older than std::thread of C++11 (which came quite late in comparison to other languages).

But when working with open source frameworks, you have to accept when some things are not always up to date. And you can make the decision yourself, if you want to use the new C++ standards or stick to your framework. It doesn't hurt to mix in the strong sides of both, though.

Best
Natu
Really, wxThread is quite a bit older than std::thread? Doesn´t look so for me, as std::thread is is really bad implemented and much harder to use then wxWidgets one. I am not expecting wxWidgets to suport the actual multithreading cocepts, but some kind of wait/notify mehanism is realy nothing new.
I prefer not to use any external APIs if posible, but since for the GUI there is no other way and wxWidgets is in my opinion the easeaest from avaible APIs, I want to keep it just 1 API.
Post Reply