我看的一下午才明白的,因为吧,我之前都是不知道与boost::thread相关的任何知识,然后开始看各种资料啊。。。

妈的,我就是一个小白,没一点基础的。。

总的来说:blocking_queue实现一个阻塞队列,它利用了生成者与消费者的设计模式,怎么说呢?、

首先吧,你要有一个queue(队列,c++里的一种容器),对它的操作有push与pop。 push即向队列里压入数据,相当于一个生产者,然后呢,pop把数据弹出队列,相当于一个消费者。。但是呢,生产者与消费者的速度可能不一样(即push与pop的速度)啊,那怎么办呢??所以呢,要想办法让它们同步啊,方法即把这样queue变为一个阻塞队列啊。。。

下面看一下怎么实现的:

它的构造函数 :

template<typename T>
BlockingQueue<T>::BlockingQueue()
: sync_(new sync()) {
}

在blockingqueue的头文件中包括:成员变量有:queue_(这是一个队列,类型为std::queue)

sync_(这是一个sync类,里面只有有两个成员变量:mutex_与condition_)

blockingqueue的成员函数:

void push(参数为一个要push进去的数据)

bool try_pop(参数为一个用于存放要pop出来的数据的指针),如果有数据可以pop出来,则返回true,否则为false

type pop(参数为一个用于存放要pop出来的数据的指针),它与上面的区别在于,如果queue为空时,它会等待。

bool try_peek(参数为一个用于存放队列最前端的数据的指针),它的作用就是试着返回一下queue最前端的数据;有数据写入,则true.

type peek(参数为一个用于存放队列最前端的数据的指针),与上面的区别在于没有数据,它会等待。

size_t size() ,它干的事情就是返回队列中数据的个数;

另外,对于blocking_queueg来说,它只会在pop与peek的时候进行相应的等待(如果队列为空就等啊),在push的时候不用等待的(应该队列不会满吧,它可以自动增加吧,应有可能取的速度较快吧,不会造成队列不断增加吧);

补充一下sync的类:

// 这个类是在BlockingQueue类中定义的
template<typename T>
class BlockingQueue<T>::sync {
public:
mutable boost::mutex mutex_;
boost::condition_variable condition_;
};

还是在这里写一下实现代码吧:

#include <boost/thread.hpp>
#include <string> #include "caffe/data_reader.hpp"
#include "caffe/layers/base_data_layer.hpp"
#include "caffe/parallel.hpp"
#include "caffe/util/blocking_queue.hpp" namespace caffe { template<typename T>
class BlockingQueue<T>::sync {
public:
mutable boost::mutex mutex_; //实现了一个mutex对象;
boost::condition_variable condition_; //也是实现了一个对象;
}; template<typename T>
BlockingQueue<T>::BlockingQueue()
: sync_(new sync()) {
} template<typename T>
void BlockingQueue<T>::push(const T& t) {
// 在push操作过程中,创建一个scoped_lock的对象lock,利用它的构造函数来对
// mutex_进行加锁;
boost::mutex::scoped_lock lock(sync_->mutex_);
queue_.push(t);
lock.unlock(); //对互斥体解锁;
sync_->condition_.notify_one(); //给相应的wait中的线程发出通知;
} template<typename T>
bool BlockingQueue<T>::try_pop(T* t) {
boost::mutex::scoped_lock lock(sync_->mutex_); if (queue_.empty()) {
return false;
} *t = queue_.front();
queue_.pop();
return true;
} template<typename T>
T BlockingQueue<T>::pop(const string& log_on_wait) {
boost::mutex::scoped_lock lock(sync_->mutex_); while (queue_.empty()) {
if (!log_on_wait.empty()) {
LOG_EVERY_N(INFO, 1000)<< log_on_wait; //当空的时候,输入相应的等待信息;
}
sync_->condition_.wait(lock); //线程进入wait的过程;等相应的通知;
} T t = queue_.front();
queue_.pop();
return t;
} template<typename T>
bool BlockingQueue<T>::try_peek(T* t) {
boost::mutex::scoped_lock lock(sync_->mutex_); if (queue_.empty()) {
return false;
} *t = queue_.front();
return true;
} template<typename T>
T BlockingQueue<T>::peek() {
boost::mutex::scoped_lock lock(sync_->mutex_); while (queue_.empty()) {
sync_->condition_.wait(lock);
} return queue_.front();
} template<typename T>
size_t BlockingQueue<T>::size() const {
boost::mutex::scoped_lock lock(sync_->mutex_);
return queue_.size();
} template class BlockingQueue<Batch<float>*>;
template class BlockingQueue<Batch<double>*>;
template class BlockingQueue<Datum*>;
template class BlockingQueue<shared_ptr<DataReader::QueuePair> >;
template class BlockingQueue<P2PSync<float>*>;
template class BlockingQueue<P2PSync<double>*>; } // namespace caffe

caffe里的blocking_queue.hpp与.cpp干了点什么呢???的更多相关文章

  1. Caffe 源碼閱讀(四) Layer.hpp Layer.cpp

    1.Setup() Layer初始化参数 (1.完成层参数的读入.处理 2.设置底层顶层的shape,在前向传播前完成) InitMutex CheckBolbCounts: LayerSetup:d ...

  2. caffe中的filler.hpp源码的作用:

    filler.hpp文件:(它应该没有对应的.cpp文件,一切实现都是在头文件中定义的,可能是因为filler只分在网络初始化时用到那么一次吧) 1,首先定义了基类:Filler,它包括:一个纯虚函数 ...

  3. Stored Procedure 里的 WITH RECOMPILE 到底是干麻的?

    在 SQL Server 创建或修改「存储过程(stored procedure)」时,可加上 WITH RECOMPILE 选项,但多数文档或书籍都写得语焉不详,或只解释为「每次执行此存储过程时,都 ...

  4. 【撸码caffe 二】 blob.hpp

    Blob类是caffe中对处理和传递的实际数据的封装,是caffe中基本的数据存储单元,包括前向传播中的图像数据,反向传播中的梯度数据以及网络层间的中间数据变量(包括权值,偏置等),训练模型的参数等等 ...

  5. 【撸码caffe 一】syncedmen.hpp

    SyncedMemory类主要负责在主机(CPU)和设备(GPU)之间管理内存分配和数据同步工作,封装了CPU和GPU之间的数据交互操作. 补充一点GPU的相关知识: 对CUDA架构而言,主机端的内存 ...

  6. caffe程序中出现的db.cpp:#line(行号) unknown database backend问题

    报错原因:lmdb不可用 解决方法:Makefile.config将此处更改 CPU_ONLY := 1 #如果只使用CPU的话就改这个,使用GPU的不需要改 USE_OPENCV := 1 #有安装 ...

  7. Faster-RCNN用于场景文字检测训练测试过程记录(转)

    [训练测试过程记录]Faster-RCNN用于场景文字检测 原创 2017年11月06日 20:09:00 标签: 609 编辑 删除 写在前面:github上面的Text-Detection-wit ...

  8. 语义分割学习之SegNet的C++编译

    Abstract 安装好Segnet并使用Python进行训练和测试之后,考虑项目的应用,需要在C++的工程环境下进行继续开发,所以这里的主要内容是用C++建立工程,使用相应的数据集和权重参数文件进行 ...

  9. caffe的data_reader.cpp分析一下干了点什么

    首先说明:下面的内容不一定对 类body: 变量:LayerParameter param_ :它里面放的是:body传进来的layerparameter的参数: BlockingQueue<s ...

随机推荐

  1. js的作用域

    全局代码和两个函数都会形成一个作用域,通过函数是在哪个作用域下创建的来确定作用域的上下级关系.作用域最大的用处是隔离变量,不同作用域下同名变量不会有冲突.

  2. fastjson和json-lib的区别

    上次把原生json替换成了fastjson,发生很多地方不兼容,对这个也做了一些总结: 1.对于没有赋值的变量处理,json-lib会根据类型给出相应初始值,而fastjson直接忽略这个字段. 解决 ...

  3. 基本的MFC多线程

    多线程程序我本来是能够来写的.但是由于在图像处理的过程中,对于这方面知识使用的比较少,造成重复忘记的情况.这里再次进行整理学习,特别注重和“图像处理”理清关系,为下一步使用奠定基础. 这里实现的是工作 ...

  4. windows下TCP服务器和客户端的实现

      服务器   1.初始化 WSAStartup(..)   2.创建Socket s = Socket ( .. )   3.绑定端口 ret = bind ( ... )   4.监听 ret = ...

  5. JAVAWeb使用POI做导出Excel

    一.需要了解的API ①HSSFWorkBook //代表一个Excel文件 ②HSSFSheet //代表一个表 ③HSSFRow //代表一个表中的某一行 ④HSSFCell //代表一个表中的某 ...

  6. centos6.5用户管理

    一.centOS6.5用户管理命令 useradd 新增用户 userdel  删除用户 passwd  修改用户密码 二.命令的使用 useradd useradd admin userdel us ...

  7. shell脚本例子集锦(习题总结)

    练习一:写一个脚本 .设定变量FILE的值为/etc/passwd .依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么 形如:(提示:LINE=`wc -l /etc/passw ...

  8. 双击Button按钮后执行的函数

    在MFC中,当在用户界面拖入一个button后,双击会进入cpp文件,实现一个按钮点击的方法如: void CtestcontorlDlg::OnBnClickedButton() { : } 理解: ...

  9. oracle分组统计某列逗号隔开数据

    所有版本的oracle都可以使用select wm_concat(name) as name from user; 但如果是oracle11g,使用select listagg(name, ',') ...

  10. Populating Display Item Value On Query In Oracle Forms

    Write Post-Query trigger for the block you want to fetch the field value for display item.ExampleBeg ...