CAFFE 源码学习笔记之五:该类实际是 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 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();
- }
- }
- }
三、总结
该类掌控了线程的生命周期,是多线程系统的基石。
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/04-01/19783244.html