https://blog.csdn.net/zhoukai216/article/details/89403363
最近在使用std::queue的时候,遇到一些奇怪的问题。我们使用std::queue来存放一些临时的缓冲数据,然后有一个线程不断地从queue里取数据,写入到文件中,之后会调用pop()函数将数据弹出。但是很奇怪的地在弹出的过程中,程序的内存占用丝毫没有减少。查了一些资料后发现,貌似std::queue底层自己有一套内存管理机制,只有在程序退出或是queue被销毁的时候才会释放这一部分内存。笔者使用的测试代码如下:
-
#include <stdio.h>
-
#include <queue>
-
#include <WinSock2.h>
-
template<typename Data>
-
class concurrent_queue
-
{
-
private:
-
std::queue<Data> the_queue;
-
public:
-
void push( const Data& data )
-
{
-
the_queue.push( data );
-
}
-
bool empty( ) const
-
{
-
return the_queue.empty( );
-
}
-
Data& front( )
-
{
-
return the_queue.front( );
-
}
-
Data const& front( ) const
-
{
-
return the_queue.front( );
-
}
-
void pop( )
-
{
-
the_queue.pop( );
-
}
-
int size( )
-
{
-
return the_queue.size( );
-
}
-
};
-
typedef struct FRAME
-
{
-
unsigned char* sPbuf;
-
int iSize;
-
};
-
int main() {
-
concurrent_queue<FRAME> frame_list;
-
FRAME f;
-
// push
-
for (int i = 0; i < 100000; i ++ ) {
-
FRAME f;
-
f.sPbuf = NULL;
-
f.sPbuf = new byte[ 1000 ];
-
f.iSize = 1000;
-
frame_list.push( f );
-
}
-
// pop
-
for (int i = 0; i < 100000; i ++ ) {
-
FRAME f2 = frame_list.front( );
-
delete [] f2.sPbuf;
-
f2.sPbuf = NULL;
-
frame_list.pop( );
-
Sleep(10);
-
printf("%d\n",i);
-
}
-
return 0;
-
}
在VS2010中编译并运行上面的代码时,发现随着pop()的调用,内存占用并没有减少。解决方法有以下几种:
l 使用list来替代queue,经测试是可行的,在pop的时候内存会减少。但是list的效率要远不如queue了。
l 考虑使用别的编译器,例如gcc,内存也会正常地减少。
l 自己写一个Queue。
贴出一个可以正常减少内存的自定义的Queue代码:
-
template<typename Data>
-
class concurrent_queue
-
{
-
private:
-
int _size;
-
struct queue_block
-
{
-
Data q[ 0x40 ];
-
unsigned short head, tail;
-
queue_block *next;
-
queue_block( ) { head = tail = 0; next = NULL; }
-
};
-
queue_block *head, *tail;
-
mutable boost::mutex the_mutex;
-
public:
-
concurrent_queue( ) { head = tail = NULL; }
-
~concurrent_queue( )
-
{
-
while ( head )
-
{
-
queue_block *p = head;
-
head = head->next;
-
delete p;
-
}
-
}
-
void push( const Data& data )
-
{
-
boost::mutex::scoped_lock lock( the_mutex );
-
if ( !head )
-
head = tail = new queue_block;
-
if ( ( ( tail->tail + 1 ) & 0x3f ) == tail->head )
-
{
-
tail->next = new queue_block;
-
tail = tail->next;
-
}
-
tail->q[ tail->tail ] = data;
-
tail->tail = ( tail->tail + 1 ) & 0x3f;
-
_size ++;
-
}
-
bool empty( ) const
-
{
-
boost::mutex::scoped_lock lock( the_mutex );
-
return head == NULL;
-
}
-
Data& front( )
-
{
-
boost::mutex::scoped_lock lock( the_mutex );
-
return head->q[ head->head ];
-
}
-
Data const& front( ) const
-
{
-
boost::mutex::scoped_lock lock( the_mutex );
-
return head->q[ head->head ];
-
}
-
void pop( )
-
{
-
boost::mutex::scoped_lock lock( the_mutex );
-
head->head = ( head->head + 1 ) & 0x3f;
-
if ( head->head == head->tail )
-
{
-
queue_block *p = head;
-
head = head->next;
-
delete p;
-
}
-
_size --;
-
}
-
int size( )
-
{
-
boost::mutex::scoped_lock lock( the_mutex );
-
return _size;
-
}
-
};