tag 标签: 队列

相关帖子
相关博文
  • 热度 16
    2011-12-7 22:46
    2484 次阅读|
    0 个评论
      6.任务等待消息队列的消息 void  *OSQPend (OS_EVENT *pevent,INT16U timeout, INT8U *err) reentrant {     OS_ENTER_CRITICAL();     pq = (OS_Q*)pevent-OSEventPtr;            /*   队列指针=当前事件指针                    */     if (pq-OSQEntries != 0){                   /*     当前消息队列中消息数 0,有消息       */         msg =*pq-OSQOut++;                    /*     OSQOut将对应的地址的消息复制到msg    */         pq-OSQEntries--;                        /*    当前队列消息数减1       */         if (pq-OSQOut ==pq-OSQEnd) {          /* 当取出指针= =最高消息队列单元时 */             pq-OSQOut =pq-OSQStart;                           //取出指针跳转到起始单元         }         OS_EXIT_CRITICAL();         *err = OS_NO_ERR;         return (msg);                            /* Return messagereceived                            */     }                                             //以下无消息情况     OSTCBCur-OSTCBStat |=OS_STAT_Q;            /* 将事件进入睡眠状态,由消息队列唤醒 */     OSTCBCur-OSTCBDly   = timeout;              /*      等待时间置入任务控制中                   */    OS_EventTaskWait(pevent);                    /*   使任务进入等待消息队列状态     */     OS_EXIT_CRITICAL();     OS_Sched();                                  /*  任务调度函数,调用一个就绪的高优先级任务运行    */     OS_ENTER_CRITICAL();     msg = OSTCBCur-OSTCBMsg;                    //接收消息=指向当前任务的消息指针     if (msg != (void *)0) {                      /* Did we get amessage?                              */        OSTCBCur-OSTCBMsg      = (void*)0;     /*   传递给消息的指针为空   */        OSTCBCur-OSTCBStat     =OS_STAT_RDY;//表示任务处于就绪状态        OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting forevent                        */         OS_EXIT_CRITICAL();         *err                    = OS_NO_ERR;//成功等待消息队列         return (msg);                            /* Return messagereceived                            */ } //以下为超时的情况     OS_EventTO(pevent);                          /* Timed out                                          */     OS_EXIT_CRITICAL();     *err = OS_TIMEOUT;                           /* Indicate atimeout occured                        */     return ((void *)0);                          /* No messagereceived                               */ } 如果调用OSQPend()函数时队列中已经存在需要的消息,那么该消息被返回给OSQPend()函数的调用者,队列中清除该消息.如果调用OSQPend()函数时队列中没有需要的消息,OSQPend()函数挂起当前任务直到得到需要的消息或超出定义的超时时间.   7.任务无等待的从消息队列中获取消息 void  *OSQAccept (OS_EVENT*pevent) reentrant { ..............................................     OS_ENTER_CRITICAL();     pq = (OS_Q*)pevent-OSEventPtr;             /*Point at queue control block   队列指针=当前事件指针                    */     if (pq-OSQEntries != 0){                   /* See if anymessages in the queue                  */         msg = *pq-OSQOut++;                     /* Yes, extract oldestmessage from the queue         */         pq-OSQEntries--;                        /* Update the number ofentries in the queue          */         if (pq-OSQOut ==pq-OSQEnd) {          /* Wrap OUTpointer if we are at the end of the queue 当输出指针=结束指针*/             pq-OSQOut =pq-OSQStart;                                             //输出指针跳转到起始指针         }     } else {         msg = (void *)0;                         /* Queue is empty                                     */     }     OS_EXIT_CRITICAL();     return (msg);                                /* Returnmessage received (or NULL)                 */ }    
  • 热度 21
    2011-12-7 22:44
    2844 次阅读|
    0 个评论
        8.清空消息队列    pq             = (OS_Q*)pevent-OSEventPtr;      /* Point toqueue storage structure              */    pq-OSQIn      =pq-OSQStart;    pq-OSQOut     =pq-OSQStart; pq-OSQEntries = 0;     9.获取消息队列的状态   消息队列状态结构 typedef struct {    void          *OSMsg;               /* Pointer to next message to beextracted from queue          */    INT16U         OSNMsgs;             /* Number of messages in messagequeue                         */    INT16U         OSQSize;             /* Size of message queue                                       */    INT8U         OSEventTbl ;  /*List of tasks waiting for event to occur        */    INT8U          OSEventGrp;          /* Group corresponding to taskswaiting for event to occur     */ } OS_Q_DATA;   INT8U  OSQQuery (OS_EVENT*pevent, OS_Q_DATA *ppdata) reentrant {     OS_ENTER_CRITICAL();  //将事件(消息队列)结构中的等待任务列表复制到pdata数据结构中     ppdata-OSEventGrp =pevent-OSEventGrp;                /*Copy message queue wait list           */     psrc              = pevent-OSEventTbl ;     pdest             = ppdata-OSEventTbl ; #if OS_EVENT_TBL_SIZE 0                                                          //当事件就绪对应表中的对应值0时     *pdest++          = *psrc++;                                                           //地址指针下移一个类型地址,获取信号量的值 #endif   #if OS_EVENT_TBL_SIZE 1     *pdest++          = *psrc++; #endif   #if OS_EVENT_TBL_SIZE 2     *pdest++          = *psrc++; #endif   #if OS_EVENT_TBL_SIZE 3     *pdest++          = *psrc++; #endif   #if OS_EVENT_TBL_SIZE 4     *pdest++          = *psrc++; #endif   #if OS_EVENT_TBL_SIZE 5     *pdest++          = *psrc++; #endif   #if OS_EVENT_TBL_SIZE 6     *pdest++          = *psrc++; #endif   #if OS_EVENT_TBL_SIZE 7     *pdest            = *psrc; #endif     pq = (OS_Q*)pevent-OSEventPtr;                                   //将队列事件指针保存到pq 中     if (pq-OSQEntries 0){                                                   //如果消息队列指针中有消息         ppdata-OSMsg =*pq-OSQOut;                        /* Get next message to return if available 将最早进入队列得消息复制到数据结构的OSMsg中 */     } else {         ppdata-OSMsg = (void*)0;     }     ppdata-OSNMsgs =pq-OSQEntries;                                       //消息队列中的消息数放置在数据结构的(OSNMsgs)中     ppdata-OSQSize =pq-OSQSize;                                              //消息队列中的消息队列容量放置在数据结构得(OSQSize)中     OS_EXIT_CRITICAL();     return (OS_NO_ERR); }  
  • 热度 22
    2011-12-7 22:41
    1902 次阅读|
    0 个评论
      4.向消息队列发送一则消息(FIFO) INT8U  OSQPost (OS_EVENT *pevent,void *msg) reentrant { ...................................... ........................................     OS_ENTER_CRITICAL();     if (pevent-OSEventGrp !=0x00) {    /* See if any task pending onqueue  是否有任务在等待该消息队列           */         OS_EventTaskRdy(pevent,msg, OS_STAT_Q);      /* Ready highestpriority task waiting on event  */         OS_EXIT_CRITICAL();         OS_Sched();                                   /* Find highestpriority task ready to run       */         return (OS_NO_ERR);     }     pq = (OS_Q*)pevent-OSEventPtr;                 /* Point to queue control block                  */     if (pq-OSQEntries =pq-OSQSize) {  /*   消息队列当前消息数=消息中可容纳的消息数                */         OS_EXIT_CRITICAL();         return (OS_Q_FULL);//返回消息队列已满     }     *pq-OSQIn++ = msg;                               /* Insertmessage into queue                     */     pq-OSQEntries++;                                 /* Update thenbr of entries in the queue        */     if (pq-OSQIn ==pq-OSQEnd) {                    /*Wrap IN ptr if we are at end of queue        */         pq-OSQIn =pq-OSQStart;                  //构成环形队列     }     OS_EXIT_CRITICAL();     return (OS_NO_ERR); }   5.向消息队列发送一则消息(LIFO)   if(pq-OSQOut == pq-OSQStart) {                 /*当插入指针=指针的起始地址(指针) */        pq-OSQOut = pq-OSQEnd;                    //插入指针跳转到最后地址(指针)     }    pq-OSQOut--;                                                //插入指针减1    *pq-OSQOut =msg;     
  • 热度 17
    2011-12-7 22:39
    1726 次阅读|
    0 个评论
    3.删除消息队列 OS_EVENT  *OSQDel (OS_EVENT*pevent, INT8U opt, INT8U *err) reentrant { ............................................ ...........................................     OS_ENTER_CRITICAL();     if (pevent-OSEventGrp !=0x00) {                      /* See if any tasks waiting on queue        */         tasks_waiting =TRUE;                              /*Yes                                     */     } else {         tasks_waiting =FALSE;                             /*No                                       */     }     switch (opt) {         case OS_DEL_NO_PEND:                               /* Delete queueonly if no task waiting     */              if (tasks_waiting ==FALSE) { //pq放回到消息队列空链表                  pq                  = pevent-OSEventPtr; /*Return OS_Q to free list                */                 pq-OSQPtr          =OSQFreeList;                  OSQFreeList         = pq;              //pevent放回到事件控制块空链表                 pevent-OSEventType = OS_EVENT_TYPE_UNUSED;                  pevent-OSEventPtr  = OSEventFreeList;    /* Return Event Control Block to freelist  */                 OSEventFreeList     = pevent;             /* Get next free event controlblock        */                 OS_EXIT_CRITICAL();                  *err = OS_NO_ERR;                  return((OS_EVENT *)0);                   /*Queue has been deleted                  */              } else {                 OS_EXIT_CRITICAL();                  *err =OS_ERR_TASK_WAITING;                  return (pevent);              }           case OS_DEL_ALWAYS:                                /* Alwaysdelete the queue                  */              while(pevent-OSEventGrp != 0x00) {         /* Ready ALL tasks waiting for queue        */                  OS_EventTaskRdy(pevent,(void *)0, OS_STAT_Q);              }              pq                  = pevent-OSEventPtr;     /* Return OS_Q to free list                 */              pq-OSQPtr          = OSQFreeList;              OSQFreeList         = pq;             pevent-OSEventType = OS_EVENT_TYPE_UNUSED;             pevent-OSEventPtr  =OSEventFreeList;        /* Return EventControl Block to free list  */              OSEventFreeList     = pevent;                 /* Get next free event controlblock        */              OS_EXIT_CRITICAL();              if (tasks_waiting ==TRUE) {                  /* Rescheduleonly if task(s) were waiting  */                  OS_Sched();                               /* Find highestpriority task ready to run  */              }              *err = OS_NO_ERR;              return ((OS_EVENT*)0);                       /* Queue hasbeen deleted                   */           default:              OS_EXIT_CRITICAL();              *err =OS_ERR_INVALID_OPT;              return (pevent);     } }
  • 热度 19
    2011-12-7 22:36
    3227 次阅读|
    0 个评论
      1. 结构   typedef struct os_q {                  /* QUEUE CONTROL BLOCK                                         */    struct os_q   *OSQPtr;              /* Link to next queue controlblock in list of free blocks     */    void         **OSQStart;            /* Pointer to start of queuedata                              */    void         **OSQEnd;              /* Pointer to end   of queue data                              */    void         **OSQIn;               /* Pointer to where next messagewill be inserted  in   the Q */    void         **OSQOut;              /* Pointer to where next messagewill be extracted from the Q  */    INT16U         OSQSize;             /* Size of queue (maximum numberof entries)                   */     INT16U        OSQEntries;          /* Currentnumber of entries in the queue                      */ } OS_Q;   .OSQPtr 用于构建单链表OSQFreeList, 一旦建立了消息队列,该域就不再有用。 .OSQStart  队列的起点 .OSQEnd  队列的终点 .OSQIn   队列入口指针 .OSQOut   队列出口指针 .OSQSize  队列大小 .OSQEntries 队列已有消息数     2. 消息队列初始化 void OS_QInit (void) reentrant { // 队列成员只有一个的情况,建立空队列单链表 #if OS_MAX_QS == 1    OSQFreeList     =OSQTbl ;      /* Only ONEqueue!                                   */    OSQFreeList-OSQPtr = (OS_Q *)0; #endif // 队列成员不止一个的情况,建立空队列单链表 #if OS_MAX_QS = 2    INT16U  i;    OS_Q   *pq1;    OS_Q   *pq2;        pq1 = OSQTbl ;    pq2 = OSQTbl ;    for (i = 0; i (OS_MAX_QS - 1); i++) {      /* Init. list of free QUEUE controlblocks            */        pq1-OSQPtr = pq2;        pq1++;        pq2++;     }    pq1-OSQPtr = (OS_Q *)0;    OSQFreeList = OSQTbl ;  //OSQFreeList 指向链表的首地址 #endif }   3. 建立一个消息队列   OS_EVENT *OSQCreate (void **start, INT16U size) reentrant { ... ... OS_ENTER_CRITICAL(); //从事件控制块空链表里取出一个    pevent = OSEventFreeList;                       if (OSEventFreeList != (OS_EVENT *)0) {         OSEventFreeList = (OS_EVENT *)OSEventFreeList-OSEventPtr;     }    OS_EXIT_CRITICAL();    if (pevent != (OS_EVENT *)0) {                       OS_ENTER_CRITICAL();  //从队列空链表里取出一个                           pq = OSQFreeList;        if (OSQFreeList != (OS_Q *)0) {                          OSQFreeList = OSQFreeList-OSQPtr;              }        OS_EXIT_CRITICAL();        if (pq != (OS_Q *)0) { // 给新的消息队列元素初始化                              pq-OSQStart        =start;                                     pq-OSQEnd          =start ;            pq-OSQIn           = start;            pq-OSQOut          = start;            pq-OSQSize         = size;            pq-OSQEntries      = 0;            pevent-OSEventType = OS_EVENT_TYPE_Q;            pevent-OSEventPtr  = pq;        //            OS_EventWaitListInit(pevent);        }   //如果没有可用的消息队列空链表,事件控制块放回空链表    else {                                        OS_ENTER_CRITICAL();                            pevent-OSEventPtr = (void *)OSEventFreeList;            OSEventFreeList    = pevent;            OS_EXIT_CRITICAL();            pevent = (OS_EVENT *)0;        } }       return(pevent);     }           示例: #define MSG_QUEUE_SIZE 2  OS_EVENT      *MsgQueue;                            void              *MsgQueueTbl ;     //指针数组            MsgQueue =OSQCreate(MsgQueueTbl , MSG_QUEUE_SIZE);
相关资源
  • 所需E币: 0
    时间: 2024-9-24 14:14
    大小: 2.82KB
    上传者: huangyasir1990
    一、MQ是什么MQ全称为MessageQueue,即消息队列,是一种提供消息队列服务的中间件,也称为消息中间件,是一套提供了消息生产、存储、消费全过程的软件系统,遵循FIFO原则。二、为什么用MQ上下班高峰期使用天府通刷码的人非常多,以为做并发量很高,一个出站请求到后台需要做费用结算,或者积分赠送等业务。由于并发很高,并且费用结算和积分等业务本来就耗时,况且支付服务也不一定能承担那么大的请求量。当服务器线程耗尽,后续请求会等待变慢,再加上高并发请求就会导致后续请求越来越慢,请求长时间等待,导致大量请求超时。并发太高,可能会导致服务器的内存上升,CPU使用率急速上升,甚至导致服务器宕掉。加入MQ后的效果高并发请求在MQ中排队,达到了消除峰值的目的,不会有大量的请求同时怼到支付系统服务异步调用,“天府通出站API”把结算消息放入MQ就可以返回“出站成功,费用稍后结算”给用户,响应时间很快服务彻底解耦,即使支付服务挂掉,也不影响“天府通出站API”正常工作,当支付系统再启动仍然可以继续消费MQ中的消息。三、MQ的使用场景1异步&解耦笔者曾经负责某电商公司的用户服务,该服务提供用户注册,查询,修改等基础功能。用户注册成功之后,需要给用户发送短信。2消峰高并发场景下,面对突然出现的请求峰值,非常容易导致系统变得不稳定,比如大量请求访问数据库,会对数据库造成极大的压力,或者系统的资源CPU、IO出现瓶颈。3消息总线所谓总线,就是像主板里的数据总线一样,具有数据的传递和交互能力,各方不直接通信,使用总线作为标准通信接口。笔者曾经服务于某彩票公司订单团队,在彩票订单的生命周期里,经过创建,拆分子订单,出票,算奖等诸多环节。每一个环节都需要不同的服务处理,每个系统都有自己独立的表,业务功能也相对独立。假如每个应用都去修改订单主表的信息,那就会相当混乱了。4延时任务用户在美团APP下单,假如没有立即支付,进入订单详情会显示倒计时,如果超过支付时间,订单就会被自动取消。非常优雅的方式是:使用消息队列的延时消息。四、RabbitMQ主要特性: 1.可靠性:提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制; 2.灵活的路由:消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用;  3.消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用;  4.队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全; 5.多种协议的支持:支持多种消息队列协议; 6.服务器端用Erlang语言编写,支持只要是你能想到的所有编程语言; 7.管理界面:RabbitMQ有一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面; 8.跟踪机制:如果消息异常,RabbitMQ提供消息跟踪机制,使用者可以找出发生了什么; 9.插件机制:提供了许多插件,来从多方面进行扩展,也可以编写自己的插件五、生产者代码示例importpika#连接到RabbitMQ服务器connection=pika.BlockingConnection(pika.ConnectionParameters('localhost'))channel=connection.channel()#声明一个队列channel.queue_declare(queue='hello')#发送消息channel.basic_publish(exchange='',           routing_key='hello',           body='HelloWorld!')print("[x]Sent'HelloWorld!'")#关闭连接connection.close()六、消费者代码示例importpika#连接到RabbitMQ服务器connection=pika.BlockingConnection(pika.ConnectionParameters('localhost'))channel=connection.channel()#声明一个队列channel.queue_declare(queue='hello')#定义消息处理函数defcallback(ch,method,properties,body):  print("[x]Received%r"%body)#设置消费者channel.basic_consume(queue='hello',           auto_ack=True,           on_message_callback=callback)print('[*]Waitingformessages.ToexitpressCTRL+C')channel.start_consuming()
  • 所需E币: 1
    时间: 2023-7-11 17:27
    大小: 889.71KB
    上传者: 张红川
    05system-VIPC通信-消息队列.pdf
  • 所需E币: 1
    时间: 2023-7-10 16:06
    大小: 463.2KB
    上传者: 张红川
    07队列.pdf。。。。。。。。。
  • 所需E币: 5
    时间: 2023-2-7 10:50
    大小: 1.1MB
    上传者: czd886
    基于消息队列遥测传输协议的智能家居消息中间件设计
  • 所需E币: 5
    时间: 2022-10-6 11:37
    大小: 1.51MB
    上传者: ZHUANG
    基于动态队列算法的高校智慧视频监控系统的设计与实现
  • 所需E币: 1
    时间: 2022-7-7 14:21
    大小: 698.31KB
    上传者: ZHUANG
    基于M_M_m队列的通信网络排队模型化研究
  • 所需E币: 1
    时间: 2022-7-7 11:22
    大小: 183.47KB
    上传者: ZHUANG
    多媒体通信网络中基于优先队列的包调度算法的改进
  • 所需E币: 1
    时间: 2022-7-7 11:19
    大小: 929.38KB
    上传者: ZHUANG
    队列方法下电力调度系统中通信网络环节动态模型的构建
  • 所需E币: 1
    时间: 2022-1-8 10:42
    大小: 925.1KB
    上传者: 西风瘦马
    raw-os实例之——消息队列(queue)
  • 所需E币: 1
    时间: 2022-1-8 10:43
    大小: 930.29KB
    上传者: 西风瘦马
    raw-os实例之——消息队列(queue_buffer)
  • 所需E币: 1
    时间: 2022-1-8 10:43
    大小: 928.87KB
    上传者: 西风瘦马
    raw-os实例之——消息队列(queue_size)
  • 所需E币: 0
    时间: 2021-9-27 16:58
    大小: 243.42KB
    上传者: Argent
    电子产品日新月异,不管是硬件工程师还是软件工程师,基本的模电、数电、微机原理、信号处理等知识是必备的条件,从二极管到三极管,从单片机到多核MCU,3G网络到5G产品的普及,不管电子产品的集成度怎么高,其产品还是少不了电阻电容电感,每个元器件在电路中必然有其作用,有兴趣了解的网友,下载学习学习吧。
  • 所需E币: 1
    时间: 2021-4-8 09:49
    大小: 3.05MB
    上传者: czd886
    基于MSComm和队列技术的LabVIEW数据采集系统设计
  • 所需E币: 0
    时间: 2021-3-7 21:15
    大小: 3.96KB
    上传者: kaidi2003
    消息队列程序源码.rar
  • 所需E币: 0
    时间: 2020-12-28 21:25
    大小: 78.89KB
    上传者: stanleylo2001
    二项队列的C语言源代码.pdf
  • 所需E币: 0
    时间: 2020-12-18 23:20
    大小: 4.24KB
    上传者: samewell
    ucos-II消息队列处理多按键--适合初学者
  • 所需E币: 1
    时间: 2020-11-26 16:22
    大小: 263.41KB
    上传者: sense1999
    1分钟搞定Scrapy分布式爬虫、队列和布隆过滤器
  • 所需E币: 0
    时间: 2020-9-25 23:59
    大小: 6.34KB
    上传者: LGWU1995
    ucos-II消息队列处理多按键--适合初学者.pdf
  • 所需E币: 0
    时间: 2020-9-10 22:33
    大小: 351.26KB
    上传者: Goodluck2020
    软件基础_1013第五章数据结构队列_树.pdf
  • 所需E币: 0
    时间: 2020-8-24 21:51
    大小: 640.03KB
    上传者: samewell
    消息队列遥测传输MQTT.pptx