15 #include "rclcpp/executors/multi_threaded_executor.hpp"
22 #include "rcpputils/scope_exit.hpp"
24 #include "rclcpp/logging.hpp"
25 #include "rclcpp/utilities.hpp"
29 MultiThreadedExecutor::MultiThreadedExecutor(
31 size_t number_of_threads,
32 bool yield_before_execute,
33 std::chrono::nanoseconds next_exec_timeout)
35 yield_before_execute_(yield_before_execute),
36 next_exec_timeout_(next_exec_timeout)
38 number_of_threads_ = number_of_threads > 0 ?
40 std::max(std::thread::hardware_concurrency(), 2U);
42 if (number_of_threads_ == 1) {
45 "MultiThreadedExecutor is used with a single thread.\n"
46 "Use the SingleThreadedExecutor instead.");
50 MultiThreadedExecutor::~MultiThreadedExecutor() {}
56 throw std::runtime_error(
"spin() called while already spinning");
58 RCPPUTILS_SCOPE_EXIT(wait_result_.reset();this->spinning.store(
false););
59 std::vector<std::thread> threads;
62 std::lock_guard wait_lock{wait_mutex_};
63 for (; thread_id < number_of_threads_ - 1; ++thread_id) {
64 auto func = std::bind(&MultiThreadedExecutor::run,
this, thread_id);
65 threads.emplace_back(func);
70 for (
auto & thread : threads) {
76 MultiThreadedExecutor::get_number_of_threads()
78 return number_of_threads_;
82 MultiThreadedExecutor::run(
size_t this_thread_number)
84 (void)this_thread_number;
88 std::lock_guard wait_lock{wait_mutex_};
96 if (yield_before_execute_) {
97 std::this_thread::yield();
102 if (any_exec.callback_group &&
103 any_exec.callback_group->type() == CallbackGroupType::MutuallyExclusive)
108 throw std::runtime_error(
110 "Failed to trigger guard condition on callback group change: ") + ex.what());
116 any_exec.callback_group.reset();
Coordinate the order and timing of available communication tasks.
std::shared_ptr< rclcpp::GuardCondition > interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
RCLCPP_PUBLIC bool get_next_executable(AnyExecutable &any_executable, std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
Wait for executable in ready state and populate union structure.
std::shared_ptr< rclcpp::Context > context_
The context associated with this executor.
RCLCPP_PUBLIC void execute_any_executable(AnyExecutable &any_exec)
Find the next available executable and do the work associated with it.
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin and to cancel blocking spins.
Created when the return code does not match one of the other specialized exceptions.
RCLCPP_PUBLIC void spin() override
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC bool ok(rclcpp::Context::SharedPtr context=nullptr)
Check rclcpp's status.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Options to be passed to the executor constructor.