变量传递过程 MapBuilder的构造函数中,对线程池进行了构造,其定义在cartographer/cartographer/mapping/map_builder.h
的类MapBuilder下
1 common::ThreadPool thread_pool_;
它的赋值在mapbuilder的构造函数里,使用options.num_background_threads()对thread_pool 进行赋值
1 2 3 4 MapBuilder::MapBuilder (const proto::MapBuilderOptions& options) : options_ (options), thread_pool_ (options.num_background_threads ()) { ... }
options.num_background_threads()参数在cartographer/configuration_files/map_build.lua
中定义。在这里,线程池的数量为4。
1 2 3 4 5 6 7 8 9 include "pose_graph.lua" MAP_BUILDER = { use_trajectory_builder_2d = false , use_trajectory_builder_3d = false , num_background_threads = 4 , pose_graph = POSE_GRAPH, collate_by_trajectory = false , }
ThreadPool构造 ThreadPool位于cartographer/common/thread_pool.h
文件中,其构造函数为
1 2 3 4 5 6 7 8 ThreadPool::ThreadPool (int num_threads) { CHECK_GT (num_threads, 0 ) << "ThreadPool requires a positive num_threads!" ; absl::MutexLock locker (&mutex_) ; for (int i = 0 ; i != num_threads; ++i) { pool_.emplace_back ([this ]() { ThreadPool::DoWork (); }); } }
简单来说,定义了几个线程数,for循环就是运行几次,每运行一次,就在pool_中添加一个线程
每一个DoWork都有一个死循环,直到执行任务队列为空,并且running_为false的时候才会结束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 void ThreadPool::DoWork () {#ifdef __linux__ CHECK_NE (nice (10 ), -1 ); #endif const auto predicate = [this ]() EXCLUSIVE_LOCKS_REQUIRED (mutex_) { return !task_queue_.empty () || !running_; }; for (;;) { std::shared_ptr<Task> task; { absl::MutexLock locker (&mutex_) ; mutex_.Await (absl::Condition (&predicate)); if (!task_queue_.empty ()) { task = std::move (task_queue_.front ()); task_queue_.pop_front (); } else if (!running_) { return ; } } CHECK (task); CHECK_EQ (task->GetState (), common::Task::DEPENDENCIES_COMPLETED); Execute (task.get ()); } }
到此现有一个印象,后续讲解后端的时候继续