1. 消息隊列
消息隊列就是一個連結清單, 存于核心之中
特點 :
- 具有特定的格式以及優先級
- 消息讀取之後, 仍然存在消息隊列中 (不同于管道通信)
- 實作消息的随機查詢, 可以按照類型查詢
- 可以實作雙方互相通訊(不同于管道通信)
相關API函數 :
#include <sys/msg.h>
//建立/擷取消息隊列 成功傳回id 失敗-1
int msgget(key_t key, int msgflg);
//第一個參數: 索引值,以此來查找隊列; 第二個參數:打開方式,一般設定為 IPC_CREAT|0777
//發送消息 成功傳回0 失敗傳回-1
int msgsnd(int msgId, const void *msgp, size_t msgsz, int msgflg);
//第一個參數: 消息隊列id号,第二個參數:要發送的内容,
//第三個參數: 發送消息的大小,第四個參數通常采用預設方式,即設定為0
//接收消息
ssize_t msgrcv(int msgId, void* msgp, size_t msgsz, long msqtyp, int msgflg);
//第二個參數:讀取消息的緩存區, 第三個參數:緩存區的大小,
//第四個參數:消息的類型(一般為整型),第五個參數通常采用預設接收方式,即設定為0
//控制消息隊列,一般用于删除 成功傳回0 失敗傳回-1
int msgctl(int msgid, int cmd, struct msgid_ds *buf);
//第二個參數: 常用模式為 IPC_RMID(移除建立的隊列),
注: 确定key值時,通常采用 ftok() 函數進行确定, 并且在使用 msgsnd()和msgget() 函數時應線構造一個結構體
//key值的确定
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
//第一個參數: 指定的檔案名 第二個參數: 子序号, 通常取 1-255整型數
//msgsnd()和msgget() 函數時應線構造一個結構體
struct msgbuf
{
long mtype;
char mtext[128];
};
具體執行個體代碼 :
①從隊列擷取資訊
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf //先定義結構體
{
long mtype; //消息隊列的類型
char mtext[128]; //消息隊列内容
};
int main()
{
int msgId;
struct msgbuf readBuf;
key_t key;
key = ftok(".", 1); //通過ftok()擷取key值
msgId = msgget(key, IPC_CREAT|0777); //建立/擷取消息隊列的id号
if(msgId == -1) //判斷是否擷取成功
{
printf("get que failure\n");
}
//從消息隊列中擷取資訊
msgrcv(msgId, &readBuf, sizeof(readBuf.mtext),888,0); //888表示消息隊列的信号, 0表示預設讀取方式
printf("get message: %s from que\n",readBuf.mtext);
//擷取資訊後,進行回報,也就是可以寫資訊到隊列
struct msgbuf sendBuf = {999,"thank you"};
msgsnd(msgId, &sendBuf, strlen(sendBuf.mtext),0);
msgctl(msgId, IPC_RMID, NULL); //删除建立的隊列,防占用記憶體
return 0;
}
②發送資訊到隊列
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf
{
long mtype;
char mtext[128];
};
int main()
{
int msgId;
struct msgbuf sendBuf = {888, "hello world"}; //定義發送的類型以及内容
key_t key;
key = ftok(".", 1); //通過ftok()擷取key值
msgId = msgget(key, IPC_CREAT|0777);
if(msgId == -1)
{
printf("get que failure\n");
}
//發送資訊到隊列
msgsnd(msgId, &sendBuf, strlen(sendBuf.mtext),0); //0表示預設不堵塞
//定義readBuf 進行接收來自隊列的回報資訊
struct msgbuf readBuf;
msgrcv(msgId, &readBuf, sizeof(readBuf.mtext),999,0); //999要和上端代碼一緻
printf("return %s from que\n",readBuf.mtext);
msgctl(msgId, IPC_RMID, NULL);
return 0;
}
兩段代碼可以實作不同程序間的通信,而且可以滿足互相通訊(即可以進行回報以及接收回報)
注: 發送資訊和讀取資訊時,應保證 key 值相同, 以及消息類型 type 相同