【caffe】internal_thread.cpp/internal_thread.hpp代码解析

thread_(线程)创建函数为:

thread_.reset(new boost::thread(&InternalThread::entry, this, device, mode, rand_seed, solver_count, root_solver));

thread_作为shared_ptr<boost::thread>对象,自然可以调用shared_ptr<boost::thread>类的成员函数reset。

但为什么可以调用boost::thread的成员函数joinable():thread_->joinable()

原因是shared_ptr<boost::thread>类对->运算符进行了重载,返回的是boost::thread的指针。

class InternalThread {
 public:
  // 构造函数和析构函数
  InternalThread() : thread_() {}
  virtual ~InternalThread();
 
  /**
   * Caffe's thread local state will be initialized using the current
   * thread values, e.g. device id, solver index etc. The random seed
   * is initialized using caffe_rng_rand.  
   *  caffe的线程局部状态将会使用当前线程值来进行初始化,当前的线程的值有设备id,solver的编号、随机数种子等
   */
  void StartInternalThread();
 
  /** Will not return until the internal thread has exited. */
  // 是否知道线程退出才返回
  void StopInternalThread();
  // 线程是否已经起来了
  bool is_started() const;
 
 protected:
  /* Implement this method in your subclass
      with the code you want your thread to run. */
  // 定义了一个虚函数,要求继承该类的必须要实现之
  virtual void InternalThreadEntry() {}
 
  /* Should be tested when running loops to exit when requested. */
  // 在当请求退出的时候应该调用该函数
  bool must_stop();
 
 private:
  void entry(int device, Caffe::Brew mode, int rand_seed, int solver_count,
      bool root_solver);
  // 内部的成员变量
  shared_ptr<boost::thread> thread_;
};
 
}  // namespace caffe

-------------------------------------------------------------------

namespace caffe {
// 析构函数,调用停止内部线程函数
InternalThread::~InternalThread() {
  StopInternalThread();
}
 
// 测试线程是否起来
bool InternalThread::is_started() const {
  return thread_ && thread_->joinable(); // 首先thread_指针不能为空,然后该线程是可等待的(joinable)
}
 
bool InternalThread::must_stop() {
  //  if interruption has been requested for the current thread, false otherwise. 见boost的doc
  return thread_ && thread_->interruption_requested();
}
 
// 初始化工作,然后
void InternalThread::StartInternalThread() {
  CHECK(!is_started()) << "Threads should persist and not be restarted.";
 
  int device = 0;
#ifndef CPU_ONLY
  CUDA_CHECK(cudaGetDevice(&device));
#endif
  Caffe::Brew mode = Caffe::mode();
  int rand_seed = caffe_rng_rand();
  int solver_count = Caffe::solver_count();
  bool root_solver = Caffe::root_solver();
 
  try {// 然后重新实例化一个thread对象给thread_指针,该线程的执行的是entry函数
    thread_.reset(new boost::thread(&InternalThread::entry, this, device, mode,
          rand_seed, solver_count, root_solver));
  } catch (std::exception& e) {
    LOG(FATAL) << "Thread exception: " << e.what();
  }
}
 
// 线程所要执行的函数
void InternalThread::entry(int device, Caffe::Brew mode, int rand_seed,
    int solver_count, bool root_solver) {
#ifndef CPU_ONLY
  CUDA_CHECK(cudaSetDevice(device));
#endif
  Caffe::set_mode(mode);
  Caffe::set_random_seed(rand_seed);
  Caffe::set_solver_count(solver_count);
  Caffe::set_root_solver(root_solver);
 
  InternalThreadEntry();
}
 
// 停止线程
void InternalThread::StopInternalThread() {
  if (is_started()) {// 如果线程已经开始
    thread_->interrupt();// 那么打断
    try {
      thread_->join();// 等待线程结束
    } catch (boost::thread_interrupted&) {//如果被打断,啥也不干,因为是自己要打断的^_^
    } catch (std::exception& e) {// 如果发生其他错误则记录到日志
      LOG(FATAL) << "Thread exception: " << e.what();
    }
  }
}
 
}  // namespace caffe

本文转自:https://blog.csdn.net/langb2014/article/details/51000007

猜你喜欢

转载自blog.csdn.net/piaopiaopiaopiaopiao/article/details/85761638