CAFFE源码学习笔记之五-internal_thread
2017-03-31 10:29
316 查看
一、前言
该类实际是boost::thread的包裹器。boost十分强大,可以不用修改就在linux和windows使用,避免了使用内核函数的移植性问题。
二、源码分析
类的构造函数就默认初始化boost::thread,析构函数直接调用线程停止函数。
成员函数包括开始线程,结束线程,判断线程是否开始,要求线程结束
具体实现:
如何开始线程?
首先,要将全局的资源搬运过来;
然后,用搬运过来的原始的全局资源初始化本线程的全局资源???
最后,初始化boost::thread。
其中entry函数就是用其他线程的全局资源初始化本线程的:
如何判断线程开始了?
线程存在且是可以等待执行的:
如何结束线程?
要想主动终结一个线程是很费劲的,caffe也没有做这种费力不讨好的事情,而是被动的等待。
caffe采取是设置must_stop()函数自动检测终结条件的退出方式。
thread里的thread_->interruption_requested()提供中断检测。
同时,caffe提供了从外部主动触发interrupt操作,然后为了使可能处于阻塞状态的线程苏醒,使用join()唤醒之。
三、总结
该类掌控了线程的生命周期,是多线程系统的基石。
该类实际是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(); } } }
三、总结
该类掌控了线程的生命周期,是多线程系统的基石。
相关文章推荐
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之五-internal_thread
- CAFFE源码学习笔记之三-common
- CAFFE源码学习笔记之三-common
- CAFFE源码学习笔记之三-common
- CAFFE源码学习笔记之三-common
- 【caffe学习笔记】python caffe报错:No module named google.protobuf.internal
- CAFFE源码学习笔记之一
- CAFFE源码学习笔记之三-common
- CAFFE源码学习笔记之一
- CAFFE源码学习笔记之一