Page 1 of 3 123 LastLast
Results 1 to 10 of 30

Thread: [C++] Boost Threads

  1. #1
    Join Date
    Nov 2007
    Beans
    88
    Distro
    Ubuntu 7.10 Gutsy Gibbon

    [C++] Boost Threads

    I am trying to create a class that contains a std::list and a boost::thread. I would like the thread maintenance function to be a class function and assign that function in the class constructor as such:
    Code:
    #include <list>
    #include "frameobject.h"
    #include <boost/thread/thread.hpp>
    
    void hello();
    
    class commandqueue
    {
    public:
        commandqueue();
        ~commandqueue();
        
    private:
        void listmaintance();
        boost::thread* thrd;
        std::list<frameobject>* m_commandqueue;    
    };
    
    commandqueue::commandqueue()
    {
        std::cout<<"Command Queue constructor called"<<std::endl;
        thrd = new boost::thread(&commandqueue::listmaintance);
        if(thrd != NULL)
        {
            thrd->join();
        }
        else
        {
            std::cout<<"Unable to allocate command thread\n";
        }
        
        m_commandqueue = new std::list<frameobject>;
        if(m_commandqueue == NULL)
        {
            std::cout<<"Unable to allocate command queue\n";
        }
    };
    
    commandqueue::~commandqueue()
    {
        std::cout<<"Command Queue destructor called"<<std::endl;
        delete thrd;
        delete m_commandqueue;
    };
          
    void commandqueue::listmaintance()
    {
      std::cout <<"Hello world, I'm a thread!"<< std::endl;
      //list maintance functionality
    };
    Is this even possible? Is there a better approach to this?

    I get the following errors:
    /usr/bin/make -f nbproject/Makefile-Debug.mk SUBPROJECTS= .build-conf
    make[1]: Entering directory `/home/iharrold/UXC'
    mkdir -p build/Debug/GNU-Linux-x86
    g++ -lboost_thread -c -g3 -gdwarf-2 -o build/Debug/GNU-Linux-x86/uxcmain.o uxcmain.cc
    /usr/include/boost/function/function_template.hpp: In member function ‘bool boost::detail::function::basic_vtable0<R, Allocator>::assign_to(F, boost::detail::function::function_buffer&) [with F = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’:
    /usr/include/boost/function/function_template.hpp:656: instantiated from ‘void boost::function0<R, Allocator>::assign_to(Functor) [with Functor = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’
    /usr/include/boost/function/function_template.hpp:513: instantiated from ‘boost::function0<R, Allocator>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boo st::is_integral<Functor>::value>::value, int>::type) [with Functor = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’
    commandqueue.h:32: instantiated from here
    /usr/include/boost/function/function_template.hpp:284: error: no matching function for call to ‘boost::detail::function::basic_vtable0<void, std::allocator<boost::function_base> >::assign_to(void (commandqueue::*&)(), boost::detail::function::function_buffer&, boost::detail::function::member_ptr_tag)’
    /usr/include/boost/function/function_template.hpp: In member function ‘void boost::detail::function::basic_vtable0<R, Allocator>::init(F) [with F = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’:
    /usr/include/boost/function/function_template.hpp:277: instantiated from ‘boost::detail::function::basic_vtable0<R, Allocator>::basic_vtable0(F) [with F = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’
    /usr/include/boost/function/function_template.hpp:655: instantiated from ‘void boost::function0<R, Allocator>::assign_to(Functor) [with Functor = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’
    /usr/include/boost/function/function_template.hpp:513: instantiated from ‘boost::function0<R, Allocator>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boo st::is_integral<Functor>::value>::value, int>::type) [with Functor = void (commandqueue::*)(), R = void, Allocator = std::allocator<boost::function_base>]’
    commandqueue.h:32: instantiated from here
    /usr/include/boost/function/function_template.hpp:298: error: no matching function for call to ‘boost::detail::function::basic_vtable0<void, std::allocator<boost::function_base> >::init(void (commandqueue::*&)(), boost::detail::function::member_ptr_tag)’
    make[1]: *** [build/Debug/GNU-Linux-x86/uxcmain.o] Error 1
    make[1]: Leaving directory `/home/iharrold/UXC'
    make: *** [.build-impl] Error 2

    Build failed. Exit value 2.
    Last edited by iharrold; November 20th, 2007 at 09:29 PM. Reason: issues have arisen

  2. #2
    Join Date
    Feb 2007
    Location
    CPH
    Beans
    88
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: [C++] Boost Threads

    Have a look at this thread, might help you

    http://ubuntuforums.org/showthread.php?t=615952

  3. #3
    Join Date
    May 2007
    Location
    Paris, France
    Beans
    927
    Distro
    Kubuntu 7.04 Feisty Fawn

    Re: [C++] Boost Threads

    First off, this is C++ not C. new can (and will) throw, so better be prepared.
    Anyway from your snippet you don't seem to need any dynamic allocation... *IF* you really do need dynamic allocation, use smart pointers (boost::scoped_ptr or std::auto_ptr) instead of raw, unguarded pointers.

    Also, the boost::thread constructor takes a boost functor as a parameter (const boost::function<void (void)>&), see Boost.Functions (optionally using boost::bind) for the exact syntax. I very seldom use those so I guess you're better off on your own.


    Code:
    #include <list>
    #include "frameobject.h"
    #include <boost/thread/thread.hpp>
    
    void hello();
    
    class commandqueue
    {
    public:
        commandqueue();
        ~commandqueue();
        
    private:
        void listmaintance();
        std::list<frameobject> m_commandqueue; // should be constructed before the thread
        // and destructed after the thread, hence the reordering
        boost::thread thrd;
    };
    
    commandqueue::commandqueue()
        : m_commandqueue(),
          thrd(/* provide a wrapper functor to listmaintenance */)
    {
        std::cout<<"Command Queue constructor called"<<std::endl;
        thrd.join();
    }
    
    commandqueue::~commandqueue()
    {
        std::cout<<"Command Queue destructor called"<<std::endl;
    };
          
    void commandqueue::listmaintance()
    {
      std::cout <<"Hello world, I'm a thread!"<< std::endl;
      //list maintance functionality
    };
    Not even tinfoil can save us now...

  4. #4
    Join Date
    Feb 2007
    Location
    CPH
    Beans
    88
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: [C++] Boost Threads

    @aks44:
    I think the point in your code, where you put "/* provide a wrapper functor to listmaintenance */" is what is giving iharrold problems.

    @iharrold:
    You can ask for more help if you need it Did my previous post help anything?

  5. #5
    Join Date
    May 2007
    Location
    Paris, France
    Beans
    927
    Distro
    Kubuntu 7.04 Feisty Fawn

    Re: [C++] Boost Threads

    Quote Originally Posted by c174 View Post
    @aks44:
    I think the point in your code, where you put "/* provide a wrapper functor to listmaintenance */" is what is giving iharrold problems.
    I know. The thing is:
    - in my post I made a point about something that was not asked (good RAII style),
    - I gave to the OP all the information needed to find the relevant boost documentation by him/herself
    - I am not willing to read those docs myself and "spoon-feed" the OP, even more when you know that I won't use this knowledge anytime soon...


    So maybe my previous post was not *the* (predigested, as you seem to suggest?) answer the OP was expecting, but I'd bet it is indeed a step in the good direction.

    Give a man a fish, etc etc...
    Not even tinfoil can save us now...

  6. #6
    Join Date
    Feb 2007
    Location
    CPH
    Beans
    88
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: [C++] Boost Threads

    If I had the predigested answer I would give it But I agree that giving a fish etc is in general also very useful.

    iharrold:
    try to put "static" in front of "void listmaintance();" in the class definition. Pointers to member-functions are not allowed - unless the member is static.

    I guess you want a new thread for each instance of "commandqueue"? It can be done, but the solution is more elaborate than the code you have now (for example let the static member function include another list and a switch)

  7. #7
    Join Date
    Nov 2007
    Beans
    88
    Distro
    Ubuntu 7.10 Gutsy Gibbon

    Re: [C++] Boost Threads

    Thank you AKS and c174, I really appreciate the feed back. Putting static in front of the class function solved it and from a cursory run, seems to work. Otherwise, I was thinking of overloading the () operator as shown in the example c174 linked too. And in this example:
    Code:
    #include <boost/thread/thread.hpp>
    #include <boost/thread/xtime.hpp>
    #include <iostream>
    
    struct thread_alarm
    {
       thread_alarm(int secs) : m_secs(secs) { }
       void operator()()
       {
           boost::xtime xt;
           boost::xtime_get(&xt, boost::TIME_UTC);
           xt.sec += m_secs;
    
           boost::thread::sleep(xt);
    
           std::cout << "alarm sounded..." << std::endl;
       }
    
       int m_secs;
    };
    
    int main(int argc, char* argv[])
    {
       int secs = 5;
       std::cout << "setting alarm for 5 seconds..." << std::endl;
       thread_alarm alarm(secs);
       boost::thread thrd(alarm);
       thrd.join();
    }
    Though, I must admit I don't fully understand the mechanism of why the struct and operator overload works like it does. I assume the operator overload overides the construction of the alarm[struct] as it is being sent to the boost::thread utility function. Or is it happening after the Join as part of the join"()"? Thus the calling of the join "()" invokes the "()" operator which maintains the thread [in this case waiting for 5 seconds].


    I'll more than likely have more issues later, since it has been nearly 4 years since I was coding last and I'm re-acquainting myself with it.

  8. #8
    Join Date
    Nov 2007
    Beans
    88
    Distro
    Ubuntu 7.10 Gutsy Gibbon

    Re: [C++] Boost Threads

    So, I was experimenting in the "threadmaintance()" function by checking a boolean:
    Code:
    void commandq::commandqueue::listmaintance()
    {
        while (!m_bisdestruct)
        {
            std::cout <<"Hello world, I'm a thread!"<< std::endl;
            sleep_seconds(1);
        }
      //list maintance functionality
    };
    sleep_seconds is just a wrapper around some boost thread sleep functionality to make it easier to use. Anyways, I get the error:

    commandqueue.h: In static member function ‘static void commandq::commandqueue::listmaintance()’:
    commandqueue.h:30: error: invalid use of member ‘commandq::commandqueue::m_bisdestruct’ in static member function
    commandqueue.cc:21: error: from this location
    So slimply putting "static" didn't solve the problem, but merely hid the problem... atleast not allowing the functionality that I want because a "static" function can only access static variables or enums, etc.. I am hoping that someone can explain to me what I am missing here. Particularly with the mechanism I posted in reply #7.
    Last edited by iharrold; November 20th, 2007 at 09:44 PM.

  9. #9
    Join Date
    Nov 2006
    Location
    Israel
    Beans
    765
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: [C++] Boost Threads

    Static member functions can only access static members - makes sense if you think about it. Just declare m_bisdestruct static and you should be good to go.
    Intel E6300 / MSI P4M890M / 2GB DDR2 677 / 80GB + 1TB SATA2 / GeForce 6200TC / DL DVD+-RW / Dell 24" U2410

  10. #10
    Join Date
    Nov 2007
    Beans
    88
    Distro
    Ubuntu 7.10 Gutsy Gibbon

    Re: [C++] Boost Threads

    Quote Originally Posted by smartbei View Post
    Static member functions can only access static members - makes sense if you think about it. Just declare m_bisdestruct static and you should be good to go.
    Thanks smartbei, but I feel simply declaring everything as static is a band-aid approach. There has to be a more oop approach to this that I am just not getting.

    Edit:
    So I was reading around the Boost library info and found this nugget:
    explicit thread(const boost::function0<void>& threadfunc);

    Effects: Starts a new thread of execution and constructs a thread object representing it. Copies threadfunc (which in turn copies the function object wrapped by threadfunc) to an internal location which persists for the lifetime of the new thread of execution. Calls operator() on the copy of the threadfunc function object in the new thread of execution.
    Postconditions: *this is joinable.
    Throws: boost::thread_resource_error if a new thread of execution cannot be started.
    So I feel I am getting closer with this code:
    Code:
    commandqueue::commandqueue() :
            m_commandqueue(),
            thrd(&commandqueue::listmaintance(this)),
            m_bisdestruct(false)    
    {
        std::cout<<"Command Queue constructor called"<<std::endl;
        thrd.join();
    };
    
    void commandqueue::listmaintance(void * pThis)
    {
        std::cout <<"Hello world, I'm a thread!"<< std::endl;
        commandqueue* pt = (commandqueue*)pThis;
        pt->workerfunction();
        //list maintance functionality
    };
    
    void commandqueue::workerfunction()
    {
        while (!m_bisdestruct)
        {
            std::cout <<"Hello world, I'm a thread!"<< std::endl;
            sleep_seconds(1);
        }
      //list maintance functionality
    };
    What I am trying to do is pass in the reference to "this" to the thread maintance function and then immediatly call out to another commandqueue function that is non-static. I get the following error however:
    commandqueue.cc: In constructor ‘commandq::commandqueue::commandqueue()’:
    commandqueue.cc:11: error: invalid lvalue in unary ‘&’
    so it appears that I cannot pass in "this". But I am still confused on the () operator mechanism.
    Last edited by iharrold; November 21st, 2007 at 12:00 AM. Reason: More info...

Page 1 of 3 123 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •