CAFFE源码学习笔记之五-internal_thread

来源:互联网 发布:怎样手机网络理财投资 编辑:程序博客网 时间:2024/05/19 16:03

一、前言
该类实际是boost::thread的包裹器。boost十分强大,可以不用修改就在linux和windows使用,避免了使用内核函数的移植性问题。

二、源码分析
类的构造函数就默认初始化boost::thread,析构函数直接调用线程停止函数。
成员函数包括开始线程,结束线程,判断线程是否开始,要求线程结束

class InternalThread { public:  InternalThread() : thread_() {}  virtual ~InternalThread();  void StartInternalThread();  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, int solver_rank, bool multiprocess);  shared_ptr<boost::thread> thread_;};}  // namespace caffe

具体实现:
如何开始线程?
首先,要将全局的资源搬运过来;
然后,用搬运过来的原始的全局资源初始化本线程的全局资源???
最后,初始化boost::thread。

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();  int solver_rank = Caffe::solver_rank();  bool multiprocess = Caffe::multiprocess();  try {    thread_.reset(new boost::thread(&InternalThread::entry, this, device, mode,          rand_seed, solver_count, solver_rank, multiprocess));//这里用函数指针加绑定参数的形式构造了thread  } catch (std::exception& e) {    LOG(FATAL) << "Thread exception: " << e.what();  }}

其中entry函数就是用其他线程的全局资源初始化本线程的:

void InternalThread::entry(int device, Caffe::Brew mode, int rand_seed,    int solver_count, int solver_rank, bool multiprocess) {#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_solver_rank(solver_rank);  Caffe::set_multiprocess(multiprocess);  InternalThreadEntry();}

如何判断线程开始了?
线程存在且是可以等待执行的:

bool InternalThread::is_started() const {  return thread_ && thread_->joinable();

如何结束线程?
要想主动终结一个线程是很费劲的,caffe也没有做这种费力不讨好的事情,而是被动的等待。
caffe采取是设置must_stop()函数自动检测终结条件的退出方式。
thread里的thread_->interruption_requested()提供中断检测。

bool InternalThread::must_stop() {  return thread_ && thread_->interruption_requested();}

同时,caffe提供了从外部主动触发interrupt操作,然后为了使可能处于阻塞状态的线程苏醒,使用join()唤醒之。

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();    }  }}

三、总结
该类掌控了线程的生命周期,是多线程系统的基石。

0 0
原创粉丝点击