java队列stl使用_使用stl的queue实现线程安全队列

简介

近日有朋友问起线程安全队列的问题。本文基于stl的queue容器实现了线程安全的队列,可多线程生产,多线程消费。同时与基于boost的circular_buffer实现的环形缓冲区相比较,性能略优(实验测试下来优势也不大,不到5%)。源码比较简单,使用stl和boost实现,并且实现了超过队列最大长度丢弃消息的功能。

实验环境准备

CPU主要参数:intel 2.3GHz,4核

内存:12G

操作系统:windows7

实验结果

线程数为0,表示生产线程和消费线程是同一线程,统一生产完后,从消费第一条开始的计算时间。

其他的是在一个线程生产,N(N>=1)个线程消费的情况。

e8d06713b7f8a0f418fef55b8180238d.png

折线图显示如图所示,可以看到使用queue实现的队列性能最优,circular_buffer其次,list稍差。

39a5e12fc3dffbce245cca1fe773fcfd.png

源码

在simplethreadqueue.h中注释的部分是使用boost的circular_buffer实现的。

simplethreadqueue.h

#ifndef CSIMPLETHREADQUEUE_H

#define CSIMPLETHREADQUEUE_H

#include

#include

#include

#include "boost/timer.hpp"

#include

#include

#include

using namespace std;

using namespace boost;

extern long g_nMaxCount;

template

class CSimpleThreadQueue

{

public:

CSimpleThreadQueue():m_nSize(0),m_nConsumed(0){/*m_container.resize(g_nMaxCount);*/}

size_t size(){return m_nSize;}

long GetConsumed(){return m_nConsumed;}

void EnQueue(T item)

{

m_mutex.lock();

while(m_nSize >= g_nMaxCount)

{

m_container.pop();

--m_nSize;

}

m_container.push(item);

//m_container.push_back(item);

++m_nSize;

m_cond.notify_one();

m_mutex.unlock();

}

void Dequeue(T& item)

{

while (true)

{

m_mutex.lock();

if ( m_nSize > 0)

break;

m_cond.wait_for(m_mutex, boost::chrono::microseconds(1));

m_mutex.unlock();

}

item = m_container.front();

m_container.pop();

//m_container.pop_front();

-- m_nSize;

++m_nConsumed;

m_mutex.unlock();

}

private:

std::queue m_container;

//circular_buffer m_container;

size_t m_nSize;

boost::mutex m_mutex;

condition_variable_any m_cond;

long m_nConsumed;

};

#endif

main.cpp

#include "simplethreadqueue.h"

#include

long g_nMaxCount = 500000;//100w

bool g_bRunning = true;

CSimpleThreadQueue g_queue;

boost::mutex g_mutex;

void CallbackMethod(string& strMessage)

{

int sum = 0;

for(int i = 0; i < 1000; ++ i)

sum += i;

//cout<

}

void ProduceMessageInit()

{

for(long long i = 0; i < g_nMaxCount; ++ i)

g_queue.EnQueue("Test message."/*std::to_string(i)*/);

}

void ProduceMessage()

{

//static long long i = 0;

while(g_bRunning)

{

g_queue.EnQueue("Test message."/*std::to_string(++i)*/);

}

}

void ConsumeMessage()

{

string strMessge;

//static timer t;

static boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();

//static long nCount = 0;

if(g_queue.size() > 0 && g_queue.GetConsumed() < g_nMaxCount)

{

g_queue.Dequeue(strMessge);

//++ nCount;

}

else

{

g_mutex.lock();

if(g_bRunning)

{

g_bRunning = false;

boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();

cout<

cout<

}

g_mutex.unlock();

}

CallbackMethod(strMessge);

}

void ConsumeAllMessage()

{

while(g_bRunning)

{

ConsumeMessage();

}

}

int main(int argc, char* argv[])

{

if(argc <= 1)//单线程先生产消息再消费模型

{

ProduceMessageInit();

ConsumeAllMessage();

return 0;

}

//单线程生产多线程消费模型

ProduceMessageInit();

thread_group tg;

tg.create_thread(boost::bind(ProduceMessage));

int nThreadCount = atoi(argv[1]);

if(nThreadCount <= 0)

return -1;

for(int i = 0; i < nThreadCount ; ++i)

tg.create_thread(boost::bind(ConsumeAllMessage));

tg.join_all();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值