LInux進程間通信之消息隊列編程實例


  本文主要通過消息隊列的編程實例來加深對消息隊列的理解.

一、消息隊列之創建

  創建一個消息隊列,需要用到一個函數:

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>

int msgget(key_t key,int msgflg);

   key:需要調用ftok函數來獲取.

  msgflg:IPC_CREAT,不存在則創建,存在則返回已有的qid.

     IPC_CREAT|IPC_EXCL,不存在則創建,存在則返回出錯.

  ftok函數原型如下:

#include<sys/types.h>
#include<sys/ipc.h>

key_t ftok(const char*pathname,int proj_id);

   ftok函數通過給定的路徑名稱取得其stat結構中的st_dev字段和st_info字段,然后將它們和項目id結合起來,然后產生一個鍵返回.

  為了方便使用,我們將創建消息隊列與獲取消息隊列封裝為兩個函數:

//創建與打開消息隊列公共函數
int MessageCommon(key_t key,int flag){
	int ret = 0;
	if((ret=msgget(key,flag))==-1){
		perror("msgget:");
		exit(-1);
	}
	return ret;
}
//創建全新的消息隊列(服務端)
int CreateMessage(key_t qid){
        //消息隊列也是具有權限結構的,因此在創建時給666權限
	return MessageCommon(qid,IPC_CREAT|IPC_EXCL|0666);
}
//打開已有的消息隊列(客戶端)
int GetMessage(key_t qid){
	return MessageCommon(qid,IPC_CREAT);
}

二、消息隊列之發送消息

  使用消息隊列發送消息用到了一個函數和一個結構體:

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>

int msgsnd(int msgid,const void* msgp,size_t magsz,int msgflg);

   msgid:消息隊列標識符

  msgp:發送的消息結構體指針

  msgsz:結構體中消息的大小(不是整個結構體的大小)

  msgflg:IPC_NOWAIT,消息隊列滿時返回-1

     0,消息隊列滿時阻塞.

  在通過msgsnd發送數據時,需要一個結構體來存放所發送的數據,及發送者的類型.

struct msgbuf{
        long mtype;        //消息類型,由用戶自定義
        char mtext[1024];//發送的消息(長度、類型可以自行指定)
}

   因此,我們將發送消息也做一層封裝:

//發送消息
void SendMessage(int msgid,const char* msg,int who){
	msgbuf buf;
	buf.mtype = who;                //消息類型
	strcpy(buf.mtext,msg);        //消息內容
	if(msgsnd(msgid,&buf,sizeof(buf.mtext),0) == -1){
		perror("msgsnd");
		DestoryMessage(msgid);
		exit(-2);
	}
}

 三、消息隊列之接收消息

  消息隊列接收消息的函數原型如下:

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>

ssize_t msgrcv(int qid,void *msgp,size_t msgsz,long msgtyp,int msgflg);

   qid:消息隊列的標識符

  msgp:消息結構體指針

  msgsz:消息內容大小

  msgtyp:消息類型

  msgflg:同上

  封裝之后的代碼如下:

void ReceiveMessage(int msgid,char* msg,int who){
	msgbuf buf;
	if(msgrcv(msgid,&buf,sizeof(buf.mtext),who,0)==-1){
		perror("msgrcv");
		DestoryMessage(msgid);
		exit(-3);
	}
	strcpy(msg,buf.mtext);
}

四、消息隊列的刪除

  其函數原型如下:

#include<sys/type.h>
#include<sys/ipc.h>
#Include<sys/msg.h>

int msgctl(int msgid,int cmd,struct msgid_ds *buf);

  msgid:消息隊列標識符

  cmd:所要采取的命令.IPC_RMID刪除消息隊列

  buf:權限信息

  封裝后函數如下:

//消息隊列的刪除
void DestoryMessage(int msgid){
	if(msgctl(msgid,IPC_RMID,NULL) == -1){
		perror("msgctl");
		exit(-4);
	}
}

   以上便是消息隊列的基本操作,關於消息隊列通信實例為節省文章篇幅,請移步至:https://github.com/gaoxiaodiao/Linux/tree/master/LinuxCode/MessageQueue


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM