Search code examples
c++pthreadsros

How do I use the pthreads in a ROS C++ Node


I am trying to use pthread library inside the ros Node, I am including it as #include <pthread>. When I run catkin_make I get the error below. I created a simple thread as std::thread m1(move, 1);

thread: No such file or directory
 #include <pthread>
          ^~~~~~~~~

The signature of the move function is void move(short axis_no, short direction = 0) and I instantiated the thread as

std::thread m1(move, 1);    
m1.join();

I tried to add the pthread library in my CmakeLists.txt as follows add_compile_options(-std=c++11 -pthread) and target_link_libraries(pthread). Is there a way I can use the pthread library inside the ros Node?

Thank you.


Solution

  • pthread is a C library available on some platforms and if you want to use the pthread_* functions you need to #include <pthread.h>.

    Since C++11 there is an abstraction layer on top of the native threading libraries which is available if you instead #include <thread>.

    You can then use std::thread - but you will still need to link with -pthread.

    Instead of hardcoding -pthread, you can let CMake find and add the appropriate library:

    find_package(Threads REQUIRED)
    target_link_libraries(your_app PRIVATE Threads::Threads)
    

    In your program, the move function needs two arguments (the function signature is void(*)(short, short) even if you have a default value for direction).

    #include <thread>
    #include <iostream>
    
    void move(short axis_no, short direction = 0) {
        std::cout << axis_no << ' ' << direction << '\n';
    }
    
    int main() {
        auto th = std::thread(move, 1, 2); // needs 2 arguments
        th.join();
    }
    

    If you want, you can create an overload to only have to supply one argument, but in that case you also need to help the compiler to select the correct overload.

    #include <thread>
    #include <iostream>
    
    void move(short axis_no, short direction) { // no default value here
        std::cout << axis_no << ' ' << direction << '\n';
    }
    
    void move(short axis_no) { // proxy function
        move(axis_no, 0);      // where 0 is default
    }
    
    int main() {
        using one = void(*)(short);
        using two = void(*)(short, short);
    
        // use one of the above type aliases to select the proper overload:
        auto th = std::thread(static_cast<one>(move), 1);
        th.join();
    }