IPC——應用三 訊息佇列
阿新 • • 發佈:2018-12-15
目錄
一:訊息佇列
1.1定義
訊息佇列是訊息的連結表,儲存在核心中,由訊息佇列識別符號 標識。
1.2設計方案
如圖所示:先呼叫msgget()獲取一個已存在,或者 建立一個新的佇列。A程序負責傳送某一型別的資料,B程序負責接受相應型別的資料。
1.3知識瞭解
一:相關結構
①訊息結構:
//假設傳送的最長訊息是512個位元組
struct mymesg{
long mtype; /* positive message type */
char mtext[512]; /*message data, or length nbytes */
}
②每個訊息佇列都會維護一個相關資料結構: msqid_ds
//訊息佇列維護資訊。 struct msqid_ds{ struct ipc_perm msg_perm; //許可權控制 msgqnum_t msg_qnum; //訊息佇列訊息數目 msglen_t msg_qbytes;//max # of bytes on queue pid_t msg_lspid; //pid of last msgsnd()上一次傳送訊息的程序 pid_t msg_lrpid; //pid of lase msgrcv()上一次接受訊息的程序 time_t msg_stime; //last_msgsnd() time time_t msg_rtime; //last_ecvsnd() time time_t msg_ctime; //last_change time }
二:相關函式
①函式:msgget
標頭檔案 函式原型: | #include<sys/msg.h> int msgget(key_t key,int flag) |
引數: | key:用於變換成一個識別符號(ID) flag:許可權,以及各種控制資訊的指定。 |
功能: | 建立一個新佇列或者開啟一個現有佇列。(主要是和其他函式配套使用,msgctl,msgsnd,msgrcv)。 |
函式返回值: | 成功返回訊息佇列ID,出錯返回-1. |
②函式:msgctl
函式原型: | int msgctl ( int msgid, int cmd , struct msqid_ds *buf); |
函式引數: | 1 msgid :佇列編號 2 cmd :(幻數),用於指定命令,IPC_STAT,IPC_SET,IPC_RMID. 3 buf:指向結構體的指標。 |
函式功能: | 對佇列進行多種操作。 |
③函式:msgsnd
函式原型: | int msgsnd ( int msgid , const void* ptr , size_t nbytes , int flag) |
函式引數: | 1 msgid:佇列編號 2 ptr :指向一個mesg的結構體(本結構體不是標頭檔案提供的) 3 nbytes: 訊息大小。 4 flag(幻數),用於指定命令,IPC_NOWAIT(非阻塞標誌)。 |
函式功能和返回值: | 將資料傳送到訊息佇列中: 成功返回0,失敗返回-1. |
④函式:msgrcv
函式原型: | int msgrcv ( int msgid , void* ptr , size_t nbytes,long type , int flag); |
函式引數: | msgid 佇列編號 ptr 指向一個mesg結構體指標 nbytes 訊息大小 type 訊息型別 flag(幻數) 用於制定命令,IPC_NOWAIT(非阻塞標誌)。 |
函式功能和返回值: | 從訊息佇列中取資料。 成功,返回訊息佇列資料部分的長度,否則返回-1。 |
二:程式碼實現
2.1傳送訊息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>
typedef struct data
{
long type;
char text[512];
}Data;
int main()
{
int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//獲取
assert(msgid != -1);
Data val;
memset(&val, 0, sizeof(Data));
val.type = 1000;
strcpy(val.text, "hello");
msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);
memset(&val, 0, sizeof(Data));
val.type = 2000;
strcpy(val.text, "world");
msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);
exit(0);
}
2.2取用訊息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>
typedef struct data
{
long type;
char text[512];
}Data;
int main()
{
int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
assert(msgid != -1);
Data val;
memset(&val, 0, sizeof(Data));
//char buff[128] = {0};
msgrcv(msgid, &val, sizeof(Data), 1000, 0);
printf("type = %d, text = %s\n", val.type, val.text);
exit(0);
}
2.3測試執行