消息隊列允許一個進程將一個消息發送到一個隊列中,另一個進程從該隊列中接收這個消息。
使用流程:
寫端:
- 使用結構體 mq_attr 設置消息隊列屬性,有四個選項:
? ? long mq_flags; ? // 隊列屬性: 0 表示阻塞
? ? long mq_maxmsg; ?// 最大消息數
? ? long mq_msgsize;// 每條消息最大字節數
? ??long mq_curmsgs; // 當前消息數(只讀)? ??通常只用設置中間兩個,其他設為0。
- 使用mq_open()創建或打開消息隊列,其返回值為消息隊列描述符(mqd_t)。
- 向消息隊列中發送消息
- 設置發送超時等待時間,也就是當消息隊列已滿的情況下繼續發送消息,超過等待時間后就丟棄這個消息。
- 定義時間規格結構體 timespec ,使用clock_gettime(CLOCK_REALTIME)將timespec設置為當前時間。
- 自己決定等待時間為多少。
- 使用mq_timedsend()發送消息。?
- 清理:使用mq_close() 關閉消息隊列描述符
讀端:
- 使用mq_open()打開消息隊列。
- 從消息隊列中讀消息。
- 設置接收超時等待時間,具體的超時處理自己決定,可以退出,也可以繼續等待。設置方式同上。
- 使用mq_timedreceive()接收消息。
- 清理:使用mq_close()關閉消息隊列;使用mq_unlink()刪除消息隊列。
代碼示例:
mq_write.cpp
#include <iostream>
#include <mqueue.h>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <time.h>
#include <string>
#include <errno.h>const char *mq_name = "/mq_name";int main(int argc, char const *argv[])
{// 1.設置消息隊列屬性struct mq_attr attr = {0, 3, 128, 0};// 2.創建或打開消息隊列mqd_t mqd = mq_open(mq_name, O_WRONLY | O_CREAT, 0664, &attr);if (mqd == (mqd_t)-1){perror("mq_open");exit(EXIT_FAILURE);}// 3.往消息隊列中寫數據while (true){std::string input;std::cout << "請輸入要傳輸的數據(exit退出):" << std::endl;std::getline(std::cin, input);// 設置5s的超時等待struct timespec st;clock_gettime(CLOCK_REALTIME, &st);st.tv_sec += 5;// 發送數據if (mq_timedsend(mqd, input.c_str(), input.size(), 0, &st) == -1){perror("mq_timedsend");if (errno == ETIMEDOUT){std::cerr << "消息隊列已滿,等待中...\n";if (input == "exit")break;continue;}}if (input == "exit")break;}// 4.清除mq_close(mqd);return 0;
}
mq_read.cpp
#include <iostream>
#include <mqueue.h>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <time.h>
#include <string>
#include <errno.h>const char *mq_name = "/mq_name";int main(int argc, char const *argv[])
{// 1.打開消息隊列mqd_t mqd = mq_open(mq_name, O_RDONLY);if (mqd == (mqd_t)-1){perror("mq_open");exit(EXIT_FAILURE);}// 2.從消息隊列中讀數據while (true){// 設置5s的超時等待struct timespec st;clock_gettime(CLOCK_REALTIME, &st);st.tv_sec += 5;// 接收數據char buffer[128] = {0};if (mq_timedreceive(mqd, buffer, 128, nullptr, &st) == -1){perror("mq_timedreceive");if (errno == ETIMEDOUT){std::cerr << "接收超時,繼續等待...\n";continue;}elsebreak;}std::string output(buffer);if (output == "exit"){break;}std::cout << "收到消息:" << output << std::endl;}// 4.清除mq_close(mqd);mq_unlink(mq_name);return 0;
}
編譯后同時執行兩個程序,效果如下: