Threads ! - multithreading with wxThread

This forum can be used to talk about general design strategies, new ideas and questions in general related to wxWidgets. If you feel your questions doesn't fit anywhere, put it here.
Post Reply
NicolasC
Earned a small fee
Earned a small fee
Posts: 23
Joined: Fri Mar 18, 2005 5:51 pm
Location: France, Grenoble
Contact:

Threads ! - multithreading with wxThread

Post by NicolasC » Tue Apr 12, 2005 3:46 pm

Hi all,

I am currently implementing wxThreads... and I encounter a few difficulties with the API.

Here are the spec. I work on :
I need to abort (stop, cancel) a wxThread.
The abort method should return after the thread is really aborted, and the memory allocated freed.

Well...

I may use wxThread::Delete().
But, as far as I understand the doc, wxThread::Delete() keeps on processing the GUI events while waiting for the thread to stop ! Indeed, i really, really do not understand why (and I don't undestand how by looking at the sources), but well, this does not match my needs...

I may then use wxThread::Wait() (then my thread would be created as detached).
But then, I have to set up my own communication system between the calling thread and the work thread itself, to let the work thread it should terminate.

Uh...
Probabily, I misunderstood smthing in the doc...

But what should I do ?
Where shall I find a basic but good and portable example ?
Thx very much,
Nicolas

PS : additionnal question 1 :=) -
I also wonder why the destructor of wxThread is not virtual...

PPS : additionnal question 2 :=) -
I seems that all the methods in wxThread are protected against concurrent access. Well, in that case, why could not I call wxThread::Delete on a detached thread - so that the function would just do nothing ?

PPPS : additionnal question 3 :=) -
My program will run on Macintosh also. In Audacity, i red that "the use of wxThread should be avoided on the mac". Is that true ? Were could I read somthing about that ?

upCASE
Site Admin
Site Admin
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Re: Threads ! - multithreading with wxThread

Post by upCASE » Tue Apr 12, 2005 4:02 pm

Hi!
NicolasC wrote: I may use wxThread::Delete().
But, as far as I understand the doc, wxThread::Delete() keeps on processing the GUI events while waiting for the thread to stop ! Indeed, i really, really do not understand why (and I don't undestand how by looking at the sources), but well, this does not match my needs...
Quoting the docs:
Calling Delete is a graceful way to terminate the thread. It asks the thread to terminate and, if the thread code is well written, the thread will terminate after the next call to TestDestroy which should happen quite soon.
This simply means that calling wxThread::Delete() will in fact do nothing, but simply set an internal status. Calling wxThread::TestDestroy() in your thread will return true. Then, you'll have to manually end the thread.

You could use wxThread::Kill() here if you really need to "abort" the thread...
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda

NicolasC
Earned a small fee
Earned a small fee
Posts: 23
Joined: Fri Mar 18, 2005 5:51 pm
Location: France, Grenoble
Contact:

Re: Threads ! - multithreading with wxThread

Post by NicolasC » Tue Apr 12, 2005 4:38 pm

Thanks upCASE.
upCASE wrote: This simply means that calling wxThread::Delete() will in fact do nothing, but simply set an internal status. Calling wxThread::TestDestroy() in your thread will return true. Then, you'll have to manually end the thread.

You could use wxThread::Kill() here if you really need to "abort" the thread...
Well, wxThread::Kill is not that funny... I suppose it callse pthread_cancel, which is really not a good function...

Indeed, in the doc :
However, if the thread doesn't call TestDestroy often enough (or at all), the function will not return immediately, but wait until the thread terminates.
which means, I guess, that wxThread::Delete waits for the thread to terminate, if it is currently running. What I really not unterstand is why the GUI events should be processed while waiting, as the following let us guess :
As it may take a long time, and the message processing is not stopped during this function execution, message handlers may be called from inside it!
Indeed, I am simply looking for un method that would :
- just return if the thread is already stopped
- set the TestDestroy() flag to true
- wait for the thread to terminate
- let me be sure that all the memory allocated for the thread was freed

...

User avatar
Ryan Norton
Moderator
Moderator
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Re: Threads ! - multithreading with wxThread

Post by Ryan Norton » Tue Apr 12, 2005 4:42 pm

NicolasC wrote: - just return if the thread is already stopped
wxThread deletes itself on destruction, so doing this would segfault
NicolasC wrote: - set the TestDestroy() flag to true
Delete()
NicolasC wrote: - wait for the thread to terminate
Wait()

NicolasC wrote: - let me be sure that all the memory allocated for the thread was freed
As mentioned, it deletes itself, so all memory is freed :).
[Mostly retired moderator, still check in to clean up some stuff]

NicolasC
Earned a small fee
Earned a small fee
Posts: 23
Joined: Fri Mar 18, 2005 5:51 pm
Location: France, Grenoble
Contact:

Post by NicolasC » Tue Apr 12, 2005 5:22 pm

Thx again.

Well, just to make sure... Sorry, but I don't really get it..

Do you mean that wxThread::Delete does not wait for the thread to terminate ?
If it does not, what means the following words found in the doc :
However, if the thread doesn't call TestDestroy often enough (or at all), the function will not return immediately, but wait until the thread terminates.
Then, could you plz give a few more info on the following (found in the doc) ?
As it may take a long time, and the message processing is not stopped during this function execution, message handlers may be called from inside it!
This is indeed not so clear to me...

Finally...
wxThread deletes itself on destruction, so doing this would segfault
Well, I had understood that this was true only for the detached threads... In Audacity, for example, they do "delete" their wxThread objects.
Anyhow, if I cannot call the destructor, and since this destructor is not virtual, how can I delete the objects that are composed with the class that inherit from wxThread (I mean : that class may be composed with mutexes, or other objects, that won't be deleted unless the destructor is called) ?

Nicolas

megabyte
I live to help wx-kind
I live to help wx-kind
Posts: 196
Joined: Tue Dec 07, 2004 8:54 pm
Location: Essen, Germany

Re: Threads ! - multithreading with wxThread

Post by megabyte » Wed Apr 13, 2005 6:01 am

NicolasC wrote: PS : additionnal question 1 :=) -
I also wonder why the destructor of wxThread is not virtual...
In ver.2.55 and 2.53 the wxThread dtor is virtual.
NicolasC wrote: Anyhow, if I cannot call the destructor, and since this destructor is not virtual, how can I delete the objects that are composed with the class that inherit from wxThread (I mean : that class may be composed with mutexes, or other objects, that won't be deleted unless the destructor is called) ?
You can use smart pointers to delete a class objects during the class destruction. And what is the reason to delete the class objects only in the destructor?

leio
Can't get richer than this
Can't get richer than this
Posts: 802
Joined: Mon Dec 27, 2004 10:46 am
Location: Estonia, Tallinn
Contact:

Post by leio » Wed Apr 13, 2005 7:18 am

NicolasC wrote: Finally...
wxThread deletes itself on destruction, so doing this would segfault
Well, I had understood that this was true only for the detached threads...
This is correct. You have to delete the wxThread object if you use a joinable thread.
NicolasC wrote: In Audacity, for example, they do "delete" their wxThread objects.
Anyhow, if I cannot call the destructor, and since this destructor is not virtual, how can I delete the objects that are composed with the class that inherit from wxThread (I mean : that class may be composed with mutexes, or other objects, that won't be deleted unless the destructor is called) ?

Nicolas
Constructors and Destructors of parent classes are called nevertheless when the derived class is constructed/destructed. Be them virtual or not.
Compilers: gcc-3.3.6, gcc-3.4.5, gcc-4.0.2, gcc-4.1.0 and MSVC6
OS's: Gentoo Linux, WinXP; WX: CVS HEAD

Project Manager of wxMUD - http://wxmud.sf.net/
Developer of wxGTK;
gtk+ port maintainer of OMGUI - http://www.omgui.org/

mtew
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sun Apr 10, 2005 3:28 pm
Location: Durham NC, USA

Post by mtew » Thu Apr 14, 2005 3:01 am

Nicolas wrote:
Constructors and Destructors of parent classes are called nevertheless
when the derived class is constructed/destructed. Be them virtual or not.

This is not entierly true. If the code doing the final deletion knows what the object really is, then everything works out. However, if the code doing the deletion is not aware that the object is a derivative of the object it thinks it is deleting and the destructor is not virtual, the derivative destructor(s) will not be called.

That particular messyness does not happen very often in real code, so it is not usually a problem. Further, wxObject declares its destructor virtual which forces all derivative destructors to be virtual. I have not checked this particular classe's ancestory so I don't know if it is a wxObject, but I'd be mildly surprised if it were not...
MTEW

NicolasC
Earned a small fee
Earned a small fee
Posts: 23
Joined: Fri Mar 18, 2005 5:51 pm
Location: France, Grenoble
Contact:

Post by NicolasC » Thu Apr 14, 2005 9:21 am

Hi again. Thx for answers.
Think I agree with you mtew, about the destruction process. AFAIK, destructor of "upper cl:asses" are called automatically (which is not the case with other methods). But this does not mean that destructor of "down classes" are called, if the destructor is not virtual.
Well, in 2.4, wxThread did not derive from wxObject, and the destructor was not virtual. I suppose this was a source of possible pb (ie : when you would handle a thread of a derived type through a pointer of wxTrhead static type), but it seems it was corrected in 2.5.

A few old and new questions in this post.
-------------------------
Found in the doc :
As it may take a long time, and the message processing is not stopped during this function execution, message handlers may be called from inside it!
I still don't understand what this means ?
Does is mean that the message handling is processed from within wxThread::Delete ? Uh, kind of strange, is not it ?
Or does it mean that message could be received (but not processed) while wxThread::Delete is waiting ?

-----------------------
wxThread on the macintosh
I red in audacity (a free sound editor based on wxWidgets) that wxThread, wxMutexes and so on are not that funny on the mac... Do you have a pointer on that question ?

----------------------
wxThread::Pause :
Does this function returns immediately, or does it wait for the thread to be paused, such as wxThread::Delete waits for the thread to be deleted ?

----------------------
wxCriticalSection and "recursivity"
I wonder what happen if a thread try to "reenter" a critical section he has already entered. Are wxCriticalSection recursive ?

I mean : in a class, we may need to protect all the public methods against concurrent access, so that two thread cannot "enter the class" at the same time. What is the basic design for that ?
Till now, I used mutexes, with a system to make it recursive.
A more comprehensible solution, I guess, would be to use criticalSection.

We then need to compose the class with a single wxCriticalSection, which is 'entered' at the begining of each method, and 'leaved' at the end.
Now, what happens when some of these methods need to call other methods in the same class ?
We then need a 'recursive' wxCriticalSection, that is a criticalSection that can be entered multiple times by a thread, then as many times as it was entered.

Are wxCriticalSection recursive ?
If they are not... Could you tell me why ? And what is the "best basic design" that corresponds to my needs ?

Well... Sorry for this long post, I had a couple of things to say, and thx for your coming answers !

For those who may be interested, I started a post concering threads in the forum dedicated to suggested improvements : http://forums.wxwidgets.org/viewtopic.php?p=7759#7759

Post Reply