Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > boost.thread - class derivated from thread

Reply
Thread Tools

boost.thread - class derivated from thread

 
 
Lars Uffmann
Guest
Posts: n/a
 
      02-11-2008
I'm a little at a loss here with the boost.thread documentation - I was
trying to find out if the thread class is destroyed upon thread
termination and I need to construct a new one for the next thread
execution of the same function, or if I can restart the old one. I
highly doubt a thread class can self-destruct, but I wanted to see when
the destructor was called. So I made a derived class myThread (or wanted
to) and I cannot seem to get the syntax for the constructor calling
thread::thread right.

So apart from looking for an answer as to how to re-execute a thread
that has ended, or if I have to delete the old one and create a new one,
I'm curious to know how to derive _any_ class from thread, with the
proper constructor syntax, equivalent to

----
class BOOST_THREAD_DECL thread : private noncopyable
{
public:
thread();
explicit thread(const function0<void>& threadfunc);
----

TIA!

Lars
 
Reply With Quote
 
 
 
 
Phil Endecott
Guest
Posts: n/a
 
      02-11-2008
Lars Uffmann wrote:
> I'm a little at a loss here with the boost.thread documentation - I was
> trying to find out if the thread class is destroyed upon thread
> termination


No it's not; the lifetimes of the thread object and the thread itself
are independent. Either the thread can terminate before the object is
destroyed, or the object can be destroyed before the thread terminates.

> and I need to construct a new one for the next thread
> execution of the same function, or if I can restart the old one.


You should create a new thread object for each new thread.

If you want to "re-start" a thread, then you'll want to have a thread
body that has a loop:

void run() {
while (1) {
.. thread body ..
}
}

thread t(&run);

You'll then need some mechanism to pass new parameters to each iteration
of the loop. Typically you'll have a "work queue", protected by some
sort of mutex; the loop will wait until the queue is non-empty and pop
the next "work" from it.

It's much simpler to create a new thread for each "work", and I suggest
doing that unless you have some good reason not to.

> I
> highly doubt a thread class can self-destruct, but I wanted to see when
> the destructor was called.


It's called when it goes out of scope, or when it's deleted if it was
allocated with new. Just like any other object.

> So I made a derived class myThread (or wanted
> to) and I cannot seem to get the syntax for the constructor calling
> thread::thread right.


This interface uses Boost::Function, and I've always used it as shown below.

> So apart from looking for an answer as to how to re-execute a thread
> that has ended, or if I have to delete the old one and create a new one,
> I'm curious to know how to derive _any_ class from thread, with the
> proper constructor syntax, equivalent to
>
> ----
> class BOOST_THREAD_DECL thread : private noncopyable
> {
> public:
> thread();
> explicit thread(const function0<void>& threadfunc);
> ----


What is BOOST_THREAD_DECL?

Untested:

class my_thread: public boost::thread
{
public:
my_thread(boost::function<void(void)> threadfunc):
boost::thread(threadfunc)
{}
};



A better place to ask these questions would be the boost users mailing list.


Phil.
 
Reply With Quote
 
 
 
 
Lars Uffmann
Guest
Posts: n/a
 
      02-11-2008
Phil Endecott wrote:
> No it's not; the lifetimes of the thread object and the thread itself
> are independent. Either the thread can terminate before the object is
> destroyed, or the object can be destroyed before the thread terminates.


Thank you!


> It's much simpler to create a new thread for each "work", and I suggest
> doing that unless you have some good reason not to.


Hmm... my idea was to activate / deactivate a thread listening for
network traffic (in the background of a graphical application) upon user
input (toggle-button). Worked fine in the Widestudio implementation of
threads, I didn't think it made sense to re-create a new thread each
time I want to re-activate it, neither to have it running inactively in
the background when the user wants it to be deactivated.

> This interface uses Boost::Function, and I've always used it as shown
> below.


Thank you for that - the boost:function thing was what I was doing wrong
- I missed that that was part of the boost namespace, while in
thread.hpp the whole class definition happens within the namespace boost.

> What is BOOST_THREAD_DECL?

Didn't bother to check - it's part of the boost thread library.

> Untested:

Untested or not, it works

> A better place to ask these questions would be the boost users mailing
> list.

Well - if boost is going to be integrated into the next C++ standard, I
hope I can avoid subscribing to yet another mailing list

Thank you again & Best Regards,

Lars
 
Reply With Quote
 
Lars Uffmann
Guest
Posts: n/a
 
      02-11-2008
Okay, now I know what annoys the heck out of me about this thread
behaviour: If I let the user click a button to deactivate the thread, I
send a signal to it so it terminates, and then I have a friggin race
condition

The thread is listening for UDP traffic, so I send it an "end of stream"
UDP-packet (self defined, data just "-1"), and now, because I have to
also delete this thread so I can create a new one, the next time one is
needed, I have to wait for the thread state to be not running and not
waiting anymore :/

Since I know there's usually lots of brainpower and developed thoughts
behind such things, by people with far more experience than myself,
maybe someone knows what the reasoning behind this design was..

And yes, I guess I'll have to join the boost users mailing list.

Best Regards,

Lars
 
Reply With Quote
 
Lars Uffmann
Guest
Posts: n/a
 
      02-11-2008
Can I deliberately destroy a boost:thread object (without calling join()
ever) once I am done starting the thread of execution? Documentation
almost seems to say so: "The converse is also possible; if a thread
object is destroyed without join() having first been called, the thread
of execution continues until its initial function completes."

Or is that undefined behaviour in some implementations of boost?

TIA,

Lars
 
Reply With Quote
 
Phil Endecott
Guest
Posts: n/a
 
      02-11-2008
Lars Uffmann wrote:
> Hmm... my idea was to activate / deactivate a thread listening for
> network traffic (in the background of a graphical application) upon user
> input (toggle-button).


So you want to stop and resume a thread? I think you need a boolean,
and to test it periodically inside the thread. If it's set, wait on a
condition until it is cleared.

>> A better place to ask these questions would be the boost users mailing
>> list.

> Well - if boost is going to be integrated into the next C++ standard


The thread and related classes proposed for C++0x are described in
N2447. If you're using the current Boost SVN HEAD version, you're using
something similar. But the current released Boost.Threads is rather
different. It's definitely not true to say that "boost is going to be
integrated into the next C++ standard", and the people who can best
answer your questions about Boost are not in this newsgroup.


Phil.
 
Reply With Quote
 
Phil Endecott
Guest
Posts: n/a
 
      02-11-2008
Lars Uffmann wrote:
> Can I deliberately destroy a boost:thread object (without calling join()
> ever) once I am done starting the thread of execution?


Yes.
 
Reply With Quote
 
Phil Endecott
Guest
Posts: n/a
 
      02-11-2008
Lars Uffmann wrote:
> Okay, now I know what annoys the heck out of me about this thread
> behaviour: If I let the user click a button to deactivate the thread, I
> send a signal to it so it terminates, and then I have a friggin race
> condition
>
> The thread is listening for UDP traffic, so I send it an "end of stream"
> UDP-packet (self defined, data just "-1"),


You need thread cancellation. No, it's not in Boost.Thread, or in
N2447. What platform are you using? But without cancellation, you're
doing the right thing.

> and now, because I have to
> also delete this thread so I can create a new one


Why do you have to wait for the first thread to terminate before
starting another one?

> Since I know there's usually lots of brainpower and developed thoughts
> behind such things, by people with far more experience than myself,
> maybe someone knows what the reasoning behind this design was..


What aspect of the design are you questioning?


Phil.
 
Reply With Quote
 
Lars Uffmann
Guest
Posts: n/a
 
      02-11-2008
Phil Endecott wrote:
> You need thread cancellation. No, it's not in Boost.Thread, or in
> N2447. What platform are you using? But without cancellation, you're
> doing the right thing.


Right now, platform is WinXP, but I was looking forward to maybe migrate
to Linux eventually. I guess since what I'm doing works fine and you
agree with it, I'll keep it that way

> Why do you have to wait for the first thread to terminate before
> starting another one?


Well - matter of design as I migrated it from WideStudio, related to my
limited unterstanding of threads. I had a global variable pointing to my
thread (no real multithreading needed, just the network traffic handler
in parallel to the wxWidgets GUI event handler). So I was initializing
the thread once in my wxApp::OnInit, and then doing a thread::Execute
whenever the user told the software to start listening, and send that
end of stream signal when the user clicked the "Stop Listening" button.
I would need the global variable as a handle to restart the thread. If -
as you replied in the other post - I can just destroy the thread object
after initial start of thread of execution, I guess I don't really need
the global variable anymore anyways.

>> Since I know there's usually lots of brainpower and developed thoughts
>> behind such things, by people with far more experience than myself,
>> maybe someone knows what the reasoning behind this design was..

> What aspect of the design are you questioning?


That a thread cannot be restarted, but instead has to be destroyed and
reconstructed.


Best Regards,

Lars
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-12-2008
On Feb 11, 1:07 pm, Lars Uffmann <(E-Mail Removed)> wrote:
> Can I deliberately destroy a boost:thread object (without
> calling join() ever) once I am done starting the thread of
> execution?


Yes, but this may have unintentional implications with regards
to the thread state. (This "feature" is probably the biggest
defect in Boost threads. But it's easy to work around.)

You should decide, up front, at creation, whether you want to
use joinable threads, or detached threads. (From what you've
described so far, it sounds like joinable.) In Boost (at least
the last version I looked at), destructing the creating thread
object before having joined makes the thread detached. If you
want a detached thread, just write a small function which you
call to start it---the boost::thread object is a local variable
in the function, and will be destructed when you return from the
function. If you want joinable threads, I'd wrap the thread
class in my own thread class, which would probably cause an
assertion failure if the destructor was called before the thread
was joined.

In your case, I think you probably should allocate the wrapped
thread dynamically; when you get the command to terminate it,
you do whatever is necessary so that it terminates, then join,
and only then delete the wrapped thread object (which in turn
would delete the boost::thread).

Alternatively, if you really only want a single thread, which
stops and starts, you should probably use boost::condition,
e.g.:

// in class, of course...
boost::mutex myMutex ;
boost::condition myCond ;
bool myIsActive ;

// called by external thread...
void activate()
{
boost::mutex::scoped_lock
l( myMutex ) ;
myIsActive = true ;
myCond.notify_all() ;
}

void deactivate()
{
boost::mutex::scoped_lock
l( myMutex ) ;
myIsActive = false ;
// do something to trigger passage through
// checkActivate() (send empty message, etc.)?
// This part could actually occur after the lock has
// been released.
}

// called by the thread itself, from time to time
void checkActivate()
{
boost::mutex::scoped_lock
l( myMutex ) ;
while ( ! myIsActive ) {
myCond.wait( l ) ;
}
}

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why derivated exception can not be pickled ? Mathieu Courtois Python 5 09-05-2012 10:18 AM
Property persistence in derivated control Ornette ASP .Net Web Controls 0 09-15-2008 09:32 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Dynamic decide derivated obj firegun9@yahoo.com.tw C++ 4 05-26-2005 02:07 PM
Default copy operator on derivated classes Alexander Tumarov C++ 1 05-01-2004 11:12 AM



Advertisments