boost.thread - class derivated from thread

Discussion in 'C++' started by Lars Uffmann, Feb 11, 2008.

  1. Lars Uffmann

    Lars Uffmann Guest

    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
     
    Lars Uffmann, Feb 11, 2008
    #1
    1. Advertising

  2. 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.
     
    Phil Endecott, Feb 11, 2008
    #2
    1. Advertising

  3. Lars Uffmann

    Lars Uffmann Guest

    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
     
    Lars Uffmann, Feb 11, 2008
    #3
  4. Lars Uffmann

    Lars Uffmann Guest

    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
     
    Lars Uffmann, Feb 11, 2008
    #4
  5. Lars Uffmann

    Lars Uffmann Guest

    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
     
    Lars Uffmann, Feb 11, 2008
    #5
  6. 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.
     
    Phil Endecott, Feb 11, 2008
    #6
  7. 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.
     
    Phil Endecott, Feb 11, 2008
    #7
  8. 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.
     
    Phil Endecott, Feb 11, 2008
    #8
  9. Lars Uffmann

    Lars Uffmann Guest

    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
     
    Lars Uffmann, Feb 11, 2008
    #9
  10. Lars Uffmann

    James Kanze Guest

    On Feb 11, 1:07 pm, 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, 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:
    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
     
    James Kanze, Feb 12, 2008
    #10
  11. In article <>,
    Lars Uffmann <> wrote:
    >
    >That a thread cannot be restarted, but instead has to be destroyed and
    >reconstructed.


    I am not sure why you'd want the parent thread to restart another
    thread. I fail to grasp your design.

    See threads as multiple workers in a company. All of them have an
    inbox for work-to-do. If there's no work to do, the worker sit idle
    waiting for stuff in its inbox. (this translate to a
    boost::condition::wait ).

    Stopping and restarting threads is not really needed in this
    abstraction.

    Sure, you can always destroy and recreate which is the equivalent of
    sack and rehire workers.

    Yannick
     
    Yannick Tremblay, Feb 15, 2008
    #11
  12. Lars Uffmann

    Lars Uffmann Guest

    Yannick Tremblay wrote:
    > I am not sure why you'd want the parent thread to restart another
    > thread. I fail to grasp your design.
    >
    > See threads as multiple workers in a company. All of them have an
    > inbox for work-to-do. If there's no work to do, the worker sit idle
    > waiting for stuff in its inbox. (this translate to a
    > boost::condition::wait ).


    I wanted the worker to sit idle, yes. Well, actually I wanted to send
    him home to enjoy his freetime, and call him back to work when I need
    him again. Thus the restart() :)
    I didn't (and still don't) see a point in keeping a thread active in the
    background (but doing nothing) if the only purpose of this thread is to
    listen for certain network traffic, and the user explicitely switched
    off that listen interface. In that case I wanted the thread to stop, and
    not take up even 1 cpu cycle until the user wants it resumed.

    Is boost::condition::wait really a better approach? Let's say some bug
    affects the condition unwanted, that would "trigger" my thread execution
    again when I don't want it to. It's like leaving the car but with the
    engine idling. If you're unlucky, something unexpected makes the forward
    gear jump in, resulting in some really bad things happening...

    Best Regards,

    Lars
     
    Lars Uffmann, Feb 18, 2008
    #12
  13. Lars Uffmann

    James Kanze Guest

    On Feb 18, 5:12 pm, Lars Uffmann <> wrote:
    > Yannick Tremblay wrote:
    > > I am not sure why you'd want the parent thread to restart another
    > > thread. I fail to grasp your design.


    > > See threads as multiple workers in a company. All of them have an
    > > inbox for work-to-do. If there's no work to do, the worker sit idle
    > > waiting for stuff in its inbox. (this translate to a
    > > boost::condition::wait ).


    > I wanted the worker to sit idle, yes. Well, actually I wanted to send
    > him home to enjoy his freetime, and call him back to work when I need
    > him again. Thus the restart() :)
    > I didn't (and still don't) see a point in keeping a thread active in the
    > background (but doing nothing) if the only purpose of this thread is to
    > listen for certain network traffic, and the user explicitely switched
    > off that listen interface. In that case I wanted the thread to stop, and
    > not take up even 1 cpu cycle until the user wants it resumed.


    I'm not sure what state you want to see the thread in. On most
    systems today, once a thread has exit'ed, there's no way of
    restarting it. And of course, a thread in a wait on a condition
    takes 0 CPU time until someone wakes it up.

    > Is boost::condition::wait really a better approach? Let's say
    > some bug affects the condition unwanted, that would "trigger"
    > my thread execution again when I don't want it to. It's like
    > leaving the car but with the engine idling. If you're unlucky,
    > something unexpected makes the forward gear jump in, resulting
    > in some really bad things happening...


    I'm afraid I don't see the difference. If someone starts a
    thread when it's not wanted, you have a problem.

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Feb 18, 2008
    #13
  14. Lars Uffmann

    Lars Uffmann Guest

    James Kanze wrote:
    > I'm not sure what state you want to see the thread in. On most
    > systems today, once a thread has exit'ed, there's no way of
    > restarting it. And of course, a thread in a wait on a condition
    > takes 0 CPU time until someone wakes it up.


    Hmmm... point taken. As I stated earlier - I have lots to learn :)


    > I'm afraid I don't see the difference. If someone starts a
    > thread when it's not wanted, you have a problem.


    I was thinking that a condition is more bug-sensitive, than a
    thread-restart() required. Of course thats human subjective impression
    which doesn't mean much in a computer world :) Readjusted my views,
    gonna have a look into the boost::condition.

    Thanks for all your time! This will surely not be the last question you
    hear from me *g*

    Best Regards,

    Lars
     
    Lars Uffmann, Feb 19, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexander Tumarov

    Default copy operator on derivated classes

    Alexander Tumarov, May 1, 2004, in forum: C++
    Replies:
    1
    Views:
    376
    Rob Williscroft
    May 1, 2004
  2. Replies:
    4
    Views:
    499
    Howard
    May 26, 2005
  3. Christopher
    Replies:
    0
    Views:
    1,459
    Christopher
    Jun 8, 2011
  4. Ornette

    Property persistence in derivated control

    Ornette, Sep 15, 2008, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    135
    Ornette
    Sep 15, 2008
  5. Mathieu Courtois

    Why derivated exception can not be pickled ?

    Mathieu Courtois, Sep 4, 2012, in forum: Python
    Replies:
    5
    Views:
    201
    Mathieu Courtois
    Sep 5, 2012
Loading...

Share This Page