訊息佇列(來自百度百科)
訊息佇列就是一個訊息的鏈表。可以把訊息看作一個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫入權限的進程可以向訊息佇列中按照一定的規則添加新訊息;對訊息佇列有讀許可權的進程則可以從訊息佇列中讀走訊息。訊息佇列是隨核心持續的。
描述程式啟動並執行過程。
首先建立了三個線程,三個線程處於同一優先順序,但由於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