[RTT例程練習] 2.8 消息隊列message queue

消息隊列(來自百度百科)

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

描述程序運行的過程。

首先創建了三個線程,三個線程處於同一優先級,但由於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.7
thread2: send message - this is message No.8
thread2: send message - this is message No.9
thread2: send message - this is message No.10
thread2: send message - this is message No.11
thread2: send message - thread1: recv msg from msg queue, the content:this is message No.0
tg 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.0
thread2: send message - this is message No.1
thread2: send message - this is message No.2
thread2: send message - this is message No.3
thread2: send message - this is message No.4
thread2: send message - this is message No.5
thread2: send message - this is message No.6
thread2: send message - this is message No.7
thread2: send message - this is message No.8
thread2: send message - this is message No.9
thread2: send message - this is message No.10
thread2: send message - this is message No.11
thread2: send message - thread1: recv msg from msg queue, the content:this is message No.0
tg queue, the content:thread2: send message - this is message No.13
thread2: send message - this is message No.14
thread2: send message - this is message No.15
message queue full, thread2 leave
thread1: recv msg from msg queue, the content:this is message No.1
thread1: recv msg from msg queue, the content:this is message No.2
thread1: recv msg from msg queue, the content:this is message No.3
thread1: recv msg from msg queue, the content:this is message No.4
thread3: send an urgent message <over>
thread1: recv msg from msg queue, the content:over
thread1: got an urgent message, leave


發佈了49 篇原創文章 · 獲贊 10 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章