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");
60 this->spinning.store(
false);
61 this->cancel_requested_.store(
false););
65 std::vector<std::thread> threads;
68 std::lock_guard wait_lock{wait_mutex_};
69 for (; thread_id < number_of_threads_ - 1; ++thread_id) {
70 auto func = std::bind(&MultiThreadedExecutor::run,
this, thread_id);
71 threads.emplace_back(func);
76 for (
auto & thread : threads) {
82 MultiThreadedExecutor::get_number_of_threads()
84 return number_of_threads_;
88 MultiThreadedExecutor::run([[maybe_unused]]
size_t this_thread_number)
93 std::lock_guard wait_lock{wait_mutex_};
101 if (yield_before_execute_) {
102 std::this_thread::yield();
107 if (any_exec.callback_group &&
108 any_exec.callback_group->type() == CallbackGroupType::MutuallyExclusive)
113 throw std::runtime_error(
115 "Failed to trigger guard condition on callback group change: ") + ex.what());
121 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 cancel_requested_
Tracks a pending cancel request that has not yet been consumed by a spin.
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin.
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(const rclcpp::Context::SharedPtr &context=rclcpp::contexts::get_global_default_context())
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.