caffe
common.cpp
namespace caffe{
// Make sure each thread can have different values.
static boost::thread_specific_ptr<Caffe> thread_instance_;
Caffe& Caffe::Get() {
if (!thread_instance_.get()) {
thread_instance_.reset(new Caffe());
}
return *(thread_instance_.get());
}
.......
class Caffe{
...
inline static bool root_solver() { return Get().root_solver_; }
...
}
}
solver.cpp uses "Caffe::root_solver()" a lot of times, and because of "static", so solver.cpp can use "Caffe::root_solver()" without creating an instance of Caffe first.
boost
http://www.boost.org/doc/libs/1_55_0/doc/html/thread/thread_local_storage.html
Thread local storage allows multi-threaded applications to have a separate instance of a given data item for each thread. Where a single-threaded application would use static or global data, this could lead to contention, deadlock or data corruption in a multi-threaded application. One example is the C errno variable, used for storing the error code related to functions from the Standard C library. It is common practice (and required by POSIX) for compilers that support multi-threaded applications to provide a separate instance of errno for each thread, in order to avoid different threads competing to read or update the value.
boost::thread_specific_ptr provides a portable mechanism for thread-local storage that works on all compilers supported by Boost.Thread. Each instance of boost::thread_specific_ptr represents a pointer to an object (such as errno) where each thread must have a distinct value. The value for the current thread can be obtained using the get() member function, or by using the * and -> pointer deference operators. Initially the pointer has a value of NULL in each thread, but the value for the current thread can be set using the reset() member function.
http://www.kingofcoders.com/viewNews.php?type=newsCpp&id=187&number=6571825070
thread_specific_ptr代表了某个全局变量的本地存储,各个线程可以各自独立地通过它访问这个全局变量的本地副本,起到了井水不犯河水的效果。
我们来看一个实际的例子,假如我们要为一个多线程的程序添加一个记录日志的功能,记录程序的运行情况。通常的做法是,建立一个全局的日志对象,然后各个线程相互竞争地访问这个全局对象,将日志消息添加到全局的日志对象中,在这个过程中,涉及共享资源的竞争,必然会影响效率。采用线程本地存储,我们为每个线程创建一个各自独立的日志对象,并交由一个全局的thread_specific_ptr进行管理,在各个线程中,可以通过这个thread_specific_ptr独立地访问各自线程的日志对象,最后在线程退出的时候,我们再将各个线程的独自记录的日志合并到一起,就成了完整的日志。在这个过程中,各个线程通过thread_specific_ptr管理的多个日志对象,各自独立,井水不犯河水,整个过程没有共享资源的竞争,自然可以提高效率。