訊息佇列程式設計
阿新 • • 發佈:2019-01-28
一 訊息佇列
訊息佇列就是一些訊息的列表,使用者可以在訊息佇列中新增訊息和讀取訊息燈。訊息佇列具有一定的FIFO特性,但是它可以實現訊息的隨機查詢,比FIFO更具有優勢。同時,這些訊息又是存在於核心中的,由“佇列ID”來標識。
二 函式學習
三 例項
在該例項當中,傳送端傳送的訊息型別設定為該程序的程序號(也可以取其他值),因此接受端根據訊息型別來確定訊息傳送者的程序號。
messagesend.c
//使用訊息佇列傳送資訊 #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #define BUFF_SIZE 512 struct message{ long msg_type; char msg_text[BUFF_SIZE]; }; void main() { key_t key=0; int qid; struct message msg; if( (key=ftok(".",'a')) == -1) { //建立鍵值失敗 printf("creat key error\n"); exit(0); } //建立訊息佇列 /***************************** 函式原型:int msgget(key_t key,int msgflg) 函式引數:key 訊息佇列的鍵值,多個程序通過它訪問一個訊息 佇列 msgflg 許可權標誌位 返回值:成功 返回訊息佇列的ID 失敗 返回-1 *****************************/ if((qid=msgget(key,IPC_CREAT|0666))==-1) { printf("msgget\n",-1); exit(0); } //列印訊息佇列的ID printf("open queue %d\n",qid); while(1) { printf("Enter some message to the queue:\n"); if((fgets(msg.msg_text,BUFF_SIZE,stdin))==NULL) { printf("no message\n"); exit(1); } msg.msg_type=getpid(); /***************************** 函式原型:int msgsnd(int msqid, const void *msqp, size_t msgsz, int msgflg) 函式引數: msqid 訊息佇列的id msqp 指向訊息結構的指標,該訊息結構msgbuf通常如下 struct msgbuf { long mtype; //訊息型別,該結構必須從這個域開始 char mtext[];//訊息正文 } msgsz 訊息正文的位元組數(不包括訊息型別指標變數) msgflg IPC_NOWAIT:若訊息無法立即傳送,函式會立刻返回 0 msgsnd:呼叫阻塞直到傳送成功為止 返回值: 成功 0 失敗 -1 *****************************/ if(msgsnd(qid,&msg,strlen(msg.msg_text),0)==-1) { printf("msgsnd error\n"); exit(0); } if(strncmp(msg.msg_text,"quit",4)==0) { break; } } exit(0); }
messagereceive.c
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #define BUFF_SIZE 512 struct message{ long msg_type; char msg_text[BUFF_SIZE]; }; void main() { int qid; key_t key; struct message msg; if( (key=ftok(".",'a')) == -1) { //建立鍵值失敗 printf("creat key error\n"); exit(0); } if((qid=msgget(key,IPC_CREAT|0666))==-1) { printf("msgget\n",-1); exit(0); } //列印訊息佇列的ID printf("open queue %d\n",qid); do { /************************ 函式原型:void *memset(void *s, int ch, size_t n); 函式描述:將s中當前位置後面的n個位元組 (typedef unsigned int size_t )用 ch 替換並返回 s ************************/ memset(msg.msg_text,0,BUFF_SIZE); /*讀取訊息佇列*/ /******************** 函式原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 函式引數:msqid 訊息佇列的ID msgp 訊息緩衝區,通msgsnd()函式的msgp msgsz 訊息正文的位元組數 (不包括訊息型別指標變數) msgtyp 0 接受訊息佇列中的第一個訊息 大於0 接受訊息佇列中第一個型別為msgtyp的訊息 小於0 接受訊息佇列中第一個型別值不小於msgtyp絕對值且型別值最小的訊息 msgflg 0 msgsnd()呼叫阻塞直到接受一條相應型別的訊息為止 函式返回值:成功 0 失敗 -1 ********************/ if(msgrcv(qid,(void *)&msg,BUFF_SIZE,0,0)<0) { printf("msgrcv\n"); exit(0); } printf("the message from %d:%s",msg.msg_type,msg.msg_text); }while(strncmp(msg.msg_text,"quit",4)); //刪除訊息佇列 /* 函式原型:int msgctl(int msgqid,int cmd,struct msgqid_ds *buf) 函式引數:msgqid 訊息佇列的佇列id cmd IPC_STAT 讀取訊息佇列的資料結構msqid_ds,並將其儲存在buf指定的地址中 IPC_SET 設定訊息佇列的資料結構msqid_ds中的ipc_perm域值,這個值取自buf引數 IPC_RMID 從核心中刪除訊息佇列 buf 描述訊息佇列的msqid_ds結構型別變數 返回值: */ if(msgctl(qid,IPC_RMID,NULL)<0) { printf("msgctl\n"); exit(0); } }
執行結果: