我看的一下午才明白的,因为吧,我之前都是不知道与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. IE6下 input 背景图滚动问题及标签规范

    ie6 背景图滚动问题: <title>ie6下input背景图滚动问题</title> <style> .box{ height:20px; width:300p ...

  2. 算法心得2:关于k个最小和问题的思考

    问题描述如下: 有k个整数数组,各包含k个元素.在每个数组中取一个元素加起来,可以得到k^k个和.求这些和中最小的k个值(重复计算的算多次). 如果同时考虑这k个数组的取值情况,其复杂程度不言而喻,并 ...

  3. 周赛-DZY Loves Chessboard 分类: 比赛 搜索 2015-08-08 15:48 4人阅读 评论(0) 收藏

    DZY Loves Chessboard time limit per test 1 second memory limit per test 256 megabytes input standard ...

  4. Y2K Accounting Bug 分类: POJ 2015-06-16 16:55 14人阅读 评论(0) 收藏

    Y2K Accounting Bug Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11222   Accepted: 56 ...

  5. Poj(1797) Dijkstra对松弛条件的变形

    题目链接:http://poj.org/problem?id=1797 题意:从路口1运货到路口n,最大的运货重量是多少?题目给出两路口间的最大载重. 思路:j加到s还是接到K下面,取两者的较大者,而 ...

  6. Java的Properties类和读取.properties文件

    一..properties文件的作用 Properties属性文件在JAVA应用程序中是经常可以看得见的,也是特别重要的一类文件.它用来配置应用程序的一些信息,不过这些信息一般都是比较少的数据,没有必 ...

  7. flask安装

    Flask简介 Flask算是小型框架,自开发伊始就被设计为可扩展的框架,它具有一个包含基本服务的强健核心.Flask有两个依赖:路由.调试.和web服务器网关接口(Web Server Gatewa ...

  8. qbxt十一系列二

    PA[题目描述]汉诺塔升级了:现在我们有N个圆盘和N个柱子,每个圆盘大小都不一样,大的圆盘不能放在小的圆盘上面,N个柱子从左到右排成一排.每次你可以将一个柱子上的最上面的圆盘移动到右边或者左边的柱子上 ...

  9. Objective-C之category

    http://blog.csdn.net/siemenliu/article/details/7835808

  10. 嵌入式linux

    嵌入式开发 1.1开发板和宿主机的连接方法:cable 电缆可以通过 串口 网络 以及 JTGA等连接方式. JTAG:国际标准测试协议对芯片内部测试对flash烧写.注意JTAG 是一种协议,具体去 ...