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