对几种队列的总结

来源:互联网 发布:网络培训怎么培训 编辑:程序博客网 时间:2024/06/05 04:15
队列1:
描述:此队列为链表形式,由于为链表,所以没有设置最大值,可以无限往后增加,直到内存使用完
typedef struct PacketList
{
byte *pkt;
int pkt_size;
PacketList *next;
}PacketList;


typedef 
struct PacketQueue 
{
  
PacketList *first_pkt, *last_pkt;
  
int nb_packets;
  
int size;
  
HANDLE mutex;
  
HANDLE cond;


}PacketQueue;






PacketQueue videoq;




int quit=0;
void packet_queue_init(PacketQueue *q) 
{
  
memset(q, 0, sizeof(PacketQueue));
  
q->mutex = CreateMutex(NULL,false,NULL);
  
//q->cond = CreateSemaphore(NULL,1,1,NULL);
q->cond=CreateEvent(NULL,false,false,NULL);//此处用事件比用信号量更好
}


int packet_queue_put(PacketQueue *q, byte *pkt,int pkt_size) 
{


  
PacketList *pkt1;
  
if(!pkt) {
    return -1;
  }
  
pkt1 = (PacketList*)malloc(sizeof(PacketList));
  
if (!pkt1)
    return -1;
  
pkt1->pkt=(byte *)malloc(pkt_size);
  
if(!pkt1->pkt)
  {
 free(pkt1);
 return -1;
  }
  
memcpy(pkt1->pkt,pkt,pkt_size);
  
pkt1->pkt_size=pkt_size;
  
pkt1->next = NULL;
  
  
  

WaitForSingleObject(q->mutex,INFINITE);
  
  
if (!q->last_pkt)
    q->first_pkt = pkt1;
  
else
    q->last_pkt->next = pkt1;
  
q->last_pkt = pkt1;
  
q->nb_packets++;
  
q->size += pkt1->pkt_size;
  
//ReleaseSemaphore(q->cond,1,NULL);
  ResetEvent(q->cond);
  
ReleaseMutex(q->mutex);
  
return 0;


}


static int packet_queue_get(PacketQueue *q, byte *pkt, int block)//pkt由外部来分配内存,要足够大才行
{
  
PacketList *pkt1;
  
int ret;
  
  
WaitForSingleObject(q->mutex,INFINITE);
  
  
for(;;) 
{
    
    
if(quit) {
      ret = -1;
      break;
    }



pkt1 = q->first_pkt;

if (pkt1) 
{

q->first_pkt = pkt1->next;

if (!q->first_pkt)
        q->last_pkt = NULL;

q->nb_packets--;

q->size -= pkt1->pkt_size;


memcpy(pkt,pkt1->pkt,pkt1->pkt_size);

free(pkt1->pkt);

free(pkt1);

ret = 1;

break;
    
} else if (!block) 
{//为0 不阻塞,为1阻塞
      
ret = 0;
      
break;
    
} else 
{

ReleaseMutex(q->mutex);

WaitForSingleObject(q->cond,INFINITE);

WaitForSingleObject(q->mutex,INFINITE);
    
}
  
}
  
ReleaseMutex(q->mutex);
  
return ret;


}


队列2:
描述:此队列有最大值,存储数据的地方为申请的一段内存区。
typedef struct _NewQueue
{
HANDLE hMutex;//互斥量事件
HANDLE hConread;//信号量
HANDLE hConwrite;//信号量
unsigned char * buf;//数据缓冲区
int bufsize;//数据缓冲区大小
int write_ptr;//写入位置
int read_ptr;//读取位置


}NewQueue;
void init_queue(NewQueue *que, int size)
{
que->hMutex=CreateMutex(NULL,false,NULL);//每个队列的互斥量事件
que->hConread=CreateSemaphore(NULL,1,1,NULL);
que->hConwrite=CreateSemaphore(NULL,1,1,NULL);
que->buf=new unsigned char[size];//给队列分配内存
que->bufsize = size;
que->read_ptr = que->write_ptr = 0;//将队列的初始读取和写入位置都变为0
}


void free_queue(NewQueue* que) 
{
WaitForSingleObject(que->hMutex,INFINITE)

if(que->buf!=NULL)
{
delete[] que->buf;
que->buf=NULL;
}
que->bufsize = 0;
que->read_ptr = que->write_ptr = 0;
ReleaseMutex(que->hMutex);
}
int put_queue(NewQueue*que, uint8_t* buf, int size,int block) 
{
int ret;
WaitForSingleObject(que->hMutex,INFINITE)
for(;;)
{
if(que->buf==NULL)
{
ret =-1;
goto end;
}

if(que->write_ptr>=que->read_ptr)
{
int nEmptyBufSize=que->bufsize-que->write_ptr+que->read_ptr;
if(nEmptyBufSize>=size)
{
int tmp_size=que->bufsize-que->write_ptr;//队列后面剩余的大小
if(size<=tmp_size)
{
memcpy(que->buf+que->write_ptr,buf,size);

}
else
{
memcpy(que->buf+que->write_ptr,buf,tmp_size);
memcpy(que->buf,buf+tmp_size,size-tmp_size);

}
que->write_ptr=(que->write_ptr+size)%que->bufsize;
ReleaseSemaphore(que->hConread,1,NULL);
ret=1;
goto end;
}
//写入内存不够
else if(!block)
{
ret=0;
goto end;
}
else
{
ReleaseMutex(que->hMutex);
WaitForSingleObject(que->hConwrite,INFINITE);
WaitForSingleObject(que->hMutex,INFINITE);
}
}
else
{
int nEmptyBufSize=que->read_ptr-que->write_ptr;
if(nEmptyBufSize>=size)
{
memcpy(que->buf+que->write_ptr,buf,size);
que->write_ptr=(que->write_ptr+size)%que->bufsize;
ReleaseSemaphore(que->hConread,1,NULL);
ret=1;
goto end;
}
//写入内存不够
else if(!block)
{
ret=0;
goto end;
}
else
{
ReleaseMutex(que->hMutex);
WaitForSingleObject(que->hConwrite,INFINITE);
WaitForSingleObject(que->hMutex,INFINITE);
}
}
}

end: ReleaseMutex(que->hMutex);
return ret;
}
int get_queue(NewQueue*que, uint8_t* buf, int size,int block) 
{
int ret;
WaitForSingleObject(que->hMutex,INFINITE)
for(;;)
{
if(que->buf==NULL)
{
ret=-1;
goto end;
}
if(que->read_ptr<=que->write_ptr)
{
int nEmptyBufferSize=que->write_ptr-que->read_ptr;
if(nEmptyBufferSize>=size)
{
memcpy(buf,que->buf+que->read_ptr,size);
que->read_ptr=(que->read_ptr+size)%que->bufsize;
ReleaseSemaphore(que->hConwrite,1,NULL);
ret=1;
goto end;
}
else if(!block)
{
ret=0;
goto end;
}
else
{
ReleaseMutex(que->hMutex);
WaitForSingleObject(que->hConread,INFINITE);
WaitForSingleObject(que->hMutex,INFINITE);
}

}
else
{
int nEmptyBufferSize=que->bufsize-que->read_ptr+que->write_ptr;
if(nEmptyBufferSize>=size)
{
int tmp_size=que->bufsize-que->read_ptr;
if(size<=tmp_size)
{
memcpy(buf,que->buf+que->read_ptr,size);
}
else
{
memcpy(buf,que->buf+que->read_ptr,tmp_size);
memcpy(buf+tmp_size,que->buf,size-tmp_size);
}
que->read_ptr=(que->read_ptr+size)%que->bufsize;
ReleaseSemaphore(que->hConwrite,1,NULL);
ret=1;
goto end;
}
else if(!block)
{
ret=0;
goto end;
}
else
{
ReleaseMutex(que->hMutex);
WaitForSingleObject(que->hConread,INFINITE);
WaitForSingleObject(que->hMutex,INFINITE);
}
}
}//for
end: ReleaseMutex(que->hMutex);
return ret;
}


队列3:
原来主控里面的形式,也是最简单的方式,用一个大的二维数组,记录数据,然后用还有一个长度数据数组 ,写入和读取的位置,控制好不要让读取的位置到写入的位置前面去就好了。




//入队列操作
int enqueue(SOAP_SOCKET sock)
{
  int status = SOAP_OK;
  int next;
  pthread_mutex_lock(&queue_cs);
  next = tail +1;
  if (next >= MAX_QUEUE) 
    next = 0;
  if (next == head) 
      status = SOAP_EOM;
  else
  {
    queue[tail] =sock;
    tail = next;
  }
  pthread_cond_signal(&queue_cv);
  pthread_mutex_unlock(&queue_cs);
  return status;
}


//出队列操作
SOAP_SOCKET dequeue()
{
  SOAP_SOCKET sock;
  pthread_mutex_lock(&queue_cs);
   while (head == tail )
   {
          pthread_cond_wait(&queue_cv,&queue_cs);
   }
  sock = queue[head++];
  if (head >= MAX_QUEUE)
        {
    head =0;
  }
  pthread_mutex_unlock(&queue_cs);
  return sock;
}
0 0
原创粉丝点击