消息隊列(報文隊列):兩個進程間通過發送數據塊的形式進行通信。一個進程把需要發送的消息通過一個函數發送到消息隊列中,另一個進程再從消息隊列中讀取該消息。
函數:
# include <sys/types.h>
# include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id); //生成下面函數的key.可認為是一個端口號
int msgget(key_t key, int msgflg);//創建消息隊列,返回消息隊列的 msgid
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);//接收消息隊 ? ?列中的消息,把接收到的內容寫入msgp中。
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//將msgp中的內容讀入消息 ? ?隊列中。
struct msgstru?
{
??long mtype; //大于0?
??char mtext[用戶指定大小];
};
msgflg:
?1.IPC_CREAT:如果沒有就創建,有就打開。
?2.IPC_EXCL:本身沒多大意義
?3.IPC_CREAT|IPC_EXCL:如果沒有就創建,有就出錯返回,保證每一次創建都是全新的。
特點:
雙向通信。?
消息隊列是隨內核持續的。只有在內核重啟或顯示刪除一個消息隊列時,才會被真正刪除。
消息隊列是基于消息的。且消息隊列的讀取不一定是先入先出。
每個消息的最大長度是有上限的(MSGMAX),每個消息隊列的總的字節
每個消息的最大長度是有上限的(MSGMAX),每個消息隊列的總的字節數是有上限的(MSGMNB),系統上消息隊列的總數也有一個上限(MSGMNI)。
可避免同步和阻塞問題。
?comm.h1?#pragma?once2?#include<stdio.h>3?#include<sys/types.h>4?#include<sys/ipc.h>5?#include<sys/msg.h>6?#include<stdlib.h>7?#include<string.h>8?9?#define?_PATH_?"."10?#define?_PROJ_ID_?0x777711?#define?_MAX_NUM_?25612?#define?_SERVER_?113?#define?_CLIENT_?214?struct?msgstru15?{16?????long?mtype;17?????char?mtext[_MAX_NUM_];18?};19?int?creat_msg_queue();20?int?get_msg_queue();21?int?send_msg(int?msgid,char*?text,long?type);22?int?recv_msg(int?msgid,char*?text,long?type);23?int?distroy_msg_queue(int?msgid);comm.c1?#include"comm.h"2?static?int?comm_msg_queue(int?flag)3?{4?????key_t?key?=?ftok(_PATH_,_PROJ_ID_);5?????if(key?==?-1)6?????{7?????????perror("ftok");8?????????return?-1;9?????}10?????int?msgid?=?msgget(key,flag);11?????if(msgid==-1)12?????{13?????????perror("msgget");14?????????return?-1;15?????}16?????return?msgid;17?}18?int?creat_msg_queue()19?{20?????return?comm_msg_queue(IPC_CREAT|IPC_EXCL|0666);21?}22?int?get_msg_queue()23?{24?????return?comm_msg_queue(IPC_CREAT);25?}26?int?send_msg(int?msgid,char?*text,long?type)27?{28?????struct?msgstru?msg;29?????msg.mtype?=?type;30?????strcpy(msg.mtext,text);31?????if(msgsnd(msgid,&msg,sizeof(msg.mtext),0)==-1)32?????{33?????????perror("msgsnd");34?????????return?-1;35?????}36?????return?0;37?}38?int?recv_msg(int?msgid,char?*text,long?type)39?{40?????struct?msgstru?msg;41?????memset(msg.mtext,'\0',sizeof(msg.mtext));42?????if(msgrcv(msgid,&msg,sizeof(msg.mtext),type,0)==-1)43?????{44?????????perror("msgrcv");45?????????return?-1;46?????}47?????strcpy(text,msg.mtext);48?????return?0;49?50?}51?int?distroy_msg_queue(int?msgid)52?{53?????if(msgctl(msgid,IPC_RMID,NULL)==-1)54?????{55?????????perror("msgctl");56?????????return?-1;57?????}58?????return?0;59?}server.c1?#include"comm.h"2?int?main()3?{???4?????int?msgid?=?creat_msg_queue();5?????if(msgid?==?-1)6?????{7?????????return?-1;8?????}9?????char?buf[_MAX_NUM_];10?????while(1)11?????{???12?????????memset(buf,'\0',sizeof(buf));13?????????fflush(stdout);14?????????printf("please?say#???");15?????????gets(buf);16?????????if(send_msg(msgid,buf,_SERVER_)==-1)17?????????{18?????????????return?-1;19?????????}???20?????????if(recv_msg(msgid,buf,_CLIENT_)==-1)21?????????{22?????????????return?-1;23?????????}24?????????printf("client:?%s\n",buf);25?????}26?????distroy_msg_queue(msgid);27?????return?0;28?}client.c1?#include"comm.h"2?int?main()3?{???4?????int?msgid?=?get_msg_queue();5?????if(msgid==-1)6?????{???7?????????return?-1;8?????}9?????char?buf[_MAX_NUM_];10?????while(1)11?????{???12?????????if(recv_msg(msgid,buf,_SERVER_)<0)13?????????{???14?????????????return?-1;15?????????}16?????????printf("server:?%s\n",buf);17?????????fflush(stdout);18?????????memset(buf,'\0',sizeof(buf));19?????????printf("please?say#??");20?????????gets(buf);21?????????if(send_msg(msgid,buf,_CLIENT_)==-1)22?????????{???23?????????????return?-1;24?????????}25?????}26?????return?0;27?}結果:[fbl@localhost?msg_queue]$?./server
please?say#???hello
client:?hi
please?say#???how?are?you?????
client:?fine,and?you?
please?say#???fine[fbl@localhost?msg_queue]$?./client
server:?hello
please?say#??hi
server:?how?are?you?
please?say#??fine,and?you?
server:?fine
please?say#
轉載于:https://blog.51cto.com/fengbaoli/1763055