C实现的延时队列设计

 仿的live555 C++的延时队列

 

#include <rtthread.h>

extern struct dqueue_ops dqops;
struct dqueue_entry
{
 rt_tick_t s_time;
 void *pframe;
 struct dqueue_entry *pnext;
};

struct dqueue_handle
{
 struct dqueue_entry priv;
 rt_uint8_t s_init;
 rt_uint8_t s_size;
 rt_tick_t s_last_sync_tick;
 //struct dqueue_entry *pfront;
 //struct dqueue_entry *prear;
 struct dqueue_ops *s_ops;
};

struct dqueue_ops
{
// void (*enqueue)(struct dqueue_handle*,struct dqueue_entry *);
// void (*enqueue_by_ptr)(struct dqueue_handle*,struct dqueue_entry *,struct dqueue_entry *);
 void (*enqueue_by_delay)(struct dqueue_handle* ,void *,rt_tick_t);
 void (*dequeue)(struct dqueue_handle* ,void (*task)(void *));
 void (*synchronize)(struct dqueue_handle*);
 //rt_uint8_t (*isempty)(struct dqueue_handle*);

};

void dq_enqueue_by_delay(struct dqueue_handle* dq,void *p,rt_tick_t delta_time);
void dq_synchronize(struct dqueue_handle* dq);
void dq_dequeue(struct dqueue_handle* dq,void (*task)(void *));
struct dqueue_handle* dq_init(struct dqueue_ops* pops);
struct dqueue_entry* dq_head(struct dqueue_handle* dq);

/*****delta_queue.c*****/

/*file:delta_queue.c
* This file is part of A2dp.
*
*Change Logs:
*Date           Author       Notes
*2015-12-1      Raid     create
*2015-12-5      Raid   merge enqueue
*/

#include "delta_queue.h"
#include <rtthread.h>

#define NULL 0
#define INT_MAX 0x7FFFFFFF

struct dqueue_entry;
struct dqueue_handle;

struct dqueue_ops dqops =
{
  dq_enqueue_by_delay,
  dq_dequeue,
  dq_synchronize
};

struct dqueue_handle* dq_init(struct dqueue_ops* pops)
{
 struct dqueue_handle* dq
  = (struct dqueue_handle* )rt_malloc(sizeof(struct dqueue_handle));
 dq->s_init = 1;
 dq->s_size = 0;
 dq->priv.s_time = INT_MAX;
 dq->priv.pnext =  (struct dqueue_entry *)dq;
 dq->s_last_sync_tick = rt_tick_get();
 dq->s_ops = pops;
 return  dq;
}

rt_uint8_t dq_is_empty(struct dqueue_handle* dq)

  return dq->s_size==0;
}

void dq_enqueue_by_delay(struct dqueue_handle* dq,void *p,rt_tick_t delta_time)
{
 struct dqueue_entry* new_entry = NULL;
 struct dqueue_entry* index_entry;

if (!dq->s_init)
  return ;
 new_entry = (struct dqueue_entry*)rt_malloc(sizeof(struct dqueue_entry));
 new_entry->pframe = p;
 index_entry = dq_head(dq);
 dq->s_size++;
 
 while(delta_time>=index_entry->pnext->s_time)
 {
  delta_time -= index_entry->pnext->s_time;
  index_entry = index_entry->pnext;
 }
 new_entry->s_time = delta_time;
 index_entry->pnext->s_time -= new_entry->s_time;

new_entry->pnext = index_entry->pnext;
 index_entry->pnext = new_entry; 
 return  ;
}

struct dqueue_entry* dq_head(struct dqueue_handle* dq)
{
 return &dq->priv;
}

/*******************ops func******************************/
void dq_synchronize(struct dqueue_handle* dq)
{
 rt_tick_t time_now  = rt_tick_get();
 rt_tick_t time_since_lastsync = 0;
 struct dqueue_entry *current_entry = dq->priv.pnext;
 if (time_now<dq->s_last_sync_tick)
 {
  //the system clock  has apparently gone back in time
  dq->s_last_sync_tick = time_now;
  return ;
 }
 time_since_lastsync = time_now - dq->s_last_sync_tick  ;
 dq->s_last_sync_tick = time_now;

while(time_since_lastsync>current_entry->s_time)
 {
  time_since_lastsync -= current_entry->s_time;
  current_entry->s_time = 0; //must do without delay
  current_entry = current_entry->pnext; 
 }
 current_entry ->s_time -= time_since_lastsync;
}

void dq_dequeue(struct dqueue_handle* dq,void (*taskfunc)() )
{
 struct dqueue_entry *current_entry = dq->priv.pnext;
 struct dqueue_entry *temp_entry = NULL;
 if(!dq_is_empty(dq))        
 {
  while(current_entry->s_time==0)
  {
   taskfunc(current_entry->pframe);
   temp_entry = current_entry;
   current_entry = current_entry->pnext;
   rt_free(temp_entry);
   dq->priv.pnext =  current_entry;

dq->s_size--;
  }
 }
}

时间: 2024-10-06 12:19:53

C实现的延时队列设计的相关文章

基于redis的延迟消息队列设计

需求背景 用户下订单成功之后隔20分钟给用户发送上门服务通知短信 订单完成一个小时之后通知用户对上门服务进行评价 业务执行失败之后隔10分钟重试一次 类似的场景比较多 简单的处理方式就是使用定时任务 假如数据比较多的时候 有的数据可能延迟比较严重,而且越来越多的定时业务导致任务调度很繁琐不好管理. 队列设计 目前可以考虑使用rabbitmq来满足需求 但是不打算使用,因为目前太多的业务使用了另外的MQ中间件. 开发前需要考虑的问题? 及时性 消费端能按时收到 同一时间消息的消费权重 可靠性 消息

消息队列设计精要【转】

消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一. 当今市面上有很多主流的消息中间件,如老牌的ActiveMQ.RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify.MetaQ.RocketMQ等. 本文不会一一介绍这些消息队列的所有特性,而是探讨一下自主开发设计一个消息队列时,你需要思考和设计的重要方面.过程中我们会参考这些成熟消息队列的很多重要思想. 本文首先会阐述什么时候你需要

消息队列设计

消息队列的价值在于复杂操作的快速返回,消息队列的问题在于消息的完整性.不丢失. 消息队列设计的难度在于消息的阻塞丢失,例如消费者消费不及时消息队列堵塞可以采取消息服务端 持久化来避免消息丢失. 同事提出了一个已经大规模并发下的方案,将消息作为http请求请求ngnix或apache由ngnix或apache 转发请求到消息队列,这样通过ngnix或apache存储到文件系统一份,并且代理给消息队列一份,这样的好处 实现了一份数据的完整存储(可供大数据离线计算)以及实时消息流转(供大数据实时计算)

消息队列设计精要(转载)

消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的ActiveMQ.RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify.MetaQ.RocketMQ等.本文不会一一介绍这些消息队列的所有特性,而是探讨一下自主开发设计一个消息队列时,你需要思考和设计的重要方面.过程中我们会参考这些成熟消息队列的很多重要思想.本文首先会阐述什么时候你需要一个消

java数据结构与算法之(Queue)队列设计与实现

[版权申明]转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53375004 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈设计与实现 java数据结构

【转】消息队列设计精要

介绍的比较全面,可以借鉴学习:原文连接:http://tech.meituan.com/mq-design.html 消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的ActiveMQ.RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify.MetaQ.RocketMQ等.本文不会一一介绍这些消息队列的所有特性,而是探讨一下自主开发设计一个消息

RabbitMQ:伪延时队列

目录 一.什么是延时队列 二.RabbitMQ实现 三. 延时队列的问题 四.解决RabbitMQ的伪延时方案 ps:伪延时队列先卖个关子,我们先了解下延时队列. 一.什么是延时队列 所谓延时队列是指消息push到队列后,监听的消费者不能第一时间获取消息,需要等到指定时间才能消费. 一般在业务里面需要对某些消息做定时发送,不想走定时任务或者是用户下单之后多长时间自动失效类似的场景可以考虑通过延时队列实现. 二.RabbitMQ实现 MQ本身并不支持直接的延时队列实现,但是我们可以通过Rabbit

springboot-rabbitmq:实现延时队列

延时队列应用于什么场景 延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费.那么,为什么需要延迟消费呢?我们来看以下的场景 网上商城下订单后30分钟后没有完成支付,取消订单(如:淘宝.去哪儿网)    系统创建了预约之后,需要在预约时间到达前一小时提醒被预约的双方参会    系统中的业务失败之后,需要重试 这些场景都非常常见,我们可以思考,比如第二个需求,系统创建了预约之后,需要在预约时间到达前一小时提醒被预约的双方参会.那么一天之中肯定是会有很多个预约的

基于rabbitMQ 消息延时队列方案 模拟电商超时未支付订单处理场景

前言 传统处理超时订单 采取定时任务轮训数据库订单,并且批量处理.其弊端也是显而易见的:对服务器.数据库性会有很大的要求,并且当处理大量订单起来会很力不从心,而且实时性也不是特别好 当然传统的手法还可以再优化一下,即存入订单的时候就算出订单的过期时间插入数据库,设置定时任务查询数据库的时候就只需要查询过期了的订单,然后再做其他的业务操作 jdk延迟队列 DelayQueue 采取jdk自带的延迟队列能很好的优化传统的处理方案,但是该方案的弊.端也是非常致命的,所有的消息数据都是存于内存之中,一旦