我看的一下午才明白的,因为吧,我之前都是不知道与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. 约瑟夫问题 java

    约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围 ...

  2. android 代码整体回退

    repo forall -c 'HAHA=`git log --before="3 days" -1 --pretty=format:"%H"`;git res ...

  3. Wall(凸包POJ 1113)

    Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 32360 Accepted: 10969 Description On ...

  4. 第十二届浙江省大学生程序设计大赛-Demacia of the Ancients 分类: 比赛 2015-06-26 14:39 30人阅读 评论(0) 收藏

    Demacia of the Ancients Time Limit: 2 Seconds Memory Limit: 65536 KB There is a popular multiplayer ...

  5. C#微信开发文档

    C#微信开发文档 开发前准备 微信公众平台链接: https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN 开发初期我们使用测 ...

  6. if for case 及多参数同时传递

    #!/bin/bash in 'start') echo "start server..." ;; 'stop') echo "stop server..." ...

  7. Apache Commons CLI 开发命令行工具示例

    概念说明Apache Commons CLI 简介 虽然各种人机交互技术飞速发展,但最传统的命令行模式依然被广泛应用于各个领域:从编译代码到系统管理,命令行因其简洁高效而备受宠爱.各种工具和系统都 提 ...

  8. Spring中MultipartHttpServletRequest实现文件上传

    Spring中MultipartHttpServletRequest实现文件上传 转贴自:http://my.oschina.net/nyniuch/blog/185266 实现图片上传  用户必须能 ...

  9. Centos6.6 tar包安装JDK

    Linux CentOS 6.6安装JDK1.7 目录 1.下载JDK 2.卸载JDK 3.安装JDK 3.1..rpm后缀格式JDK安装方式 3.2..tar.gz后缀格式JDK安装方式 4.验证安 ...

  10. Python3基础 三元表达式实例

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...