您的位置:首页 > Web前端

CAFFE源码学习笔记之五-internal_thread

2017-03-31 10:29 316 查看
一、前言

该类实际是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();
}
}
}


三、总结

该类掌控了线程的生命周期,是多线程系统的基石。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: