[RTT常式練習] 2.8 訊息佇列message queue

來源:互聯網
上載者:User

訊息佇列(來自百度百科)

訊息佇列就是一個訊息的鏈表。可以把訊息看作一個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫入權限的進程可以向訊息佇列中按照一定的規則添加新訊息;對訊息佇列有讀許可權的進程則可以從訊息佇列中讀走訊息。訊息佇列是隨核心持續的。

描述程式啟動並執行過程。

首先建立了三個線程,三個線程處於同一優先順序,但由於thread1首先被啟動,所以它先運行,thread2,3緊隨其後。thread3中調用了delay 5s,所以一開始便被掛起了。thread1由於要等訊息佇列的訊息,而此時訊息佇列為空白,所以也被掛起了。

所以thread2便開始調用rt_mq_send() 發送訊息,但由於thread1和thread2處於同一個優先順序,所以雖然thread1等待的條件滿足了,但仍舊不能從就緒態轉為運行態。等到thread2的時間片用完之後(這裡是50),thread1便開始運行。也就出現了如下的情況,thread2列印的資訊被打斷了。

thread2: send message - this is message No.7thread2: send message - this is message No.8thread2: send message - this is message No.9thread2: send message - this is message No.10thread2: send message - this is message No.11thread2: send message - thread1: recv msg from msg queue, the content:this is message No.0tg queue, the content:thread2: send message - this is message No.13

thread1收到一個訊息後,繼續delay,這時thread2繼續發送,直道隊列滿之後退出調度。thread3 delay  5s 之後,開始調度,它發送了一條 urgent message,所謂urgent message 就是立馬放到訊息佇列的最前端,thread1收到 此訊息後也退出了調度。

程式:

#include <rtthread.h>#include <string.h>void rt_init_thread_entry(void *parameter){}#define MSG_VIP "over"static struct rt_messagequeue mq;static rt_uint8_t msg_pool[2048];static rt_uint8_t thread1_stack[1024];struct rt_thread thread1;static void thread1_entry(void *parameter){    char buf[128];        while (1)    {        rt_memset(&buf[0], 0, sizeof(buf));                if (rt_mq_recv(&mq, &buf[0], sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)        {            rt_kprintf("thread1: recv msg from msg queue, the content:%s\n", buf);                        if (strcmp(buf, MSG_VIP) == 0)                break;        }                rt_thread_delay(RT_TICK_PER_SECOND);    }        rt_kprintf("thread1: got an urgent message, leave.\n");}static rt_uint8_t thread2_stack[1024];struct rt_thread thread2;static void thread2_entry(void *parameter){    int i, result;    char buf[128];        i = 0;    while (1)    {        rt_snprintf(buf, sizeof(buf), "this is message NO.%d", i);                result = rt_mq_send(&mq, &buf[0], sizeof(buf));        if (result == -RT_EFULL)            break ;                rt_kprintf("thread2: send message - %s\n", buf);                i++;    }        rt_kprintf("message queue full, thread2 leave.\n");}   static rt_uint8_t thread3_stack[1024];struct rt_thread thread3;static void thread3_entry(void *parameter){    char msg[] = MSG_VIP;    rt_err_t result;        rt_thread_delay(RT_TICK_PER_SECOND * 5);    rt_kprintf("thread3: send an urgent message <%s> \n", msg);        do     {        result = rt_mq_urgent(&mq, &msg[0], sizeof(msg));                if (result != RT_EOK)            rt_thread_delay(20);    } while (result != RT_EOK);}int rt_application_init(){    rt_thread_t init_thread;    rt_err_t result;        result = rt_mq_init(&mq, "mqt",         &msg_pool[0], /* 記憶體池指向msg_pool */         128 - sizeof(void*), /* 每個訊息的大小是 128 - void* */        sizeof(msg_pool), /* 記憶體池的大小是msg_pool的大小 */        RT_IPC_FLAG_FIFO);/* 如果有多個線程等待,按照先來先得到的方法分配訊息 */    if (result != RT_EOK)    {        rt_kprintf("init message queue failed.\n");        return -1;    }        init_thread = rt_thread_create("init",        rt_init_thread_entry, RT_NULL,        2048, 8, 20);    if (init_thread != RT_NULL)        rt_thread_startup(init_thread);        rt_thread_init(&thread1,        "t1",        thread1_entry, RT_NULL,        &thread1_stack[0], sizeof(thread1_stack),        10, 50);    rt_thread_startup(&thread1);          rt_thread_init(&thread2,                   "thread2",                   thread2_entry,                   RT_NULL,                   &thread2_stack[0],                   sizeof(thread2_stack),10,50);    rt_thread_startup(&thread2);    rt_thread_init(&thread3,                   "thread3",                   thread3_entry,                   RT_NULL,                   &thread3_stack[0],                   sizeof(thread3_stack),10,50);    rt_thread_startup(&thread3);         return 0;}

輸出結果:

thread2: send message - this is message No.0thread2: send message - this is message No.1thread2: send message - this is message No.2thread2: send message - this is message No.3thread2: send message - this is message No.4thread2: send message - this is message No.5thread2: send message - this is message No.6thread2: send message - this is message No.7thread2: send message - this is message No.8thread2: send message - this is message No.9thread2: send message - this is message No.10thread2: send message - this is message No.11thread2: send message - thread1: recv msg from msg queue, the content:this is message No.0tg queue, the content:thread2: send message - this is message No.13thread2: send message - this is message No.14thread2: send message - this is message No.15message queue full, thread2 leavethread1: recv msg from msg queue, the content:this is message No.1thread1: recv msg from msg queue, the content:this is message No.2thread1: recv msg from msg queue, the content:this is message No.3thread1: recv msg from msg queue, the content:this is message No.4thread3: send an urgent message <over>thread1: recv msg from msg queue, the content:overthread1: got an urgent message, leave

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.