1,首先,我們應該說清楚什么是消息隊列?(以下為網(wǎng)絡資料) 消息隊列提供了一種從一個進程向另一個進程發(fā)送一個數(shù)據(jù)塊的?方法。 每個數(shù)據(jù)塊都被認 為是有一個類型,接收者進程接收的數(shù)據(jù)塊可以有不同的類型值。 可以這么說消息隊列就是一個消息的鏈表。每個消息隊列都有一個隊列頭,用結構struct msg_queue來描述。隊列頭中包含了該消息隊列的大量信息,包括消息隊列鍵值、用戶ID、組ID、消息隊列中消息數(shù)目等等。 2,這是消息隊列的結構
第一行為ipC對象數(shù)據(jù)結構。 3,如何創(chuàng)建消息隊列并且使用它?我們需要用到一些函數(shù)。 原型:int msgget(key_t key, int msgflg); 參數(shù): key:可以認為是?一個端??口號,也可以由函數(shù)ftok?生成。 msgflg: IPC_CREAT 如果IPC不存在,則創(chuàng)建?一個IPC資源,否則打開操作。 IPC_EXCL:只有在共享內存不存在的時候,新的共享內存才建?立,否則就產?生錯誤。 如果單獨使?用IPC_CREAT,XXXget()函數(shù)要么返回?一個已經存在的共享內存的操作符,要 么返回?一個新建的共享內存的標識符。 如果將IPC_CREAT和IPC_EXCL標志?一起使?用,XXXget()將返回?一個新建的IPC標識符 ;如果該IPC資源已存在,或者返回-1。 IPC_EXEL標志本?身并沒有太?大的意義,但是和IPC_CREAT標志?一起使?用可以?用來保證 所得的對象是新建的,?而不是打開已有的對象。 2.向隊列讀/寫消息 原型: **msgrcv從隊列中取?用消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);** msgsnd將數(shù)據(jù)放到消息隊列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 參數(shù): msqid:消息隊列的標識碼 msgp:指向消息緩沖區(qū)的指針,此位置?用來暫時存儲發(fā)送和接收的消息,是一個?用戶可 定義的通?用結構,形態(tài)如下: struct msgstru{ long mtype; //大于0 } msgsz:消息的?大?小。 msgtyp:從消息隊列內讀取的消息形態(tài)。如果值為零,則表?示消息隊列中的所有消息都 會被讀取。 msgflg:?用來指明核?心程序在隊列沒有數(shù)據(jù)的情況下所應采取的?行動。如果msgflg和常 數(shù)IPC_NOWAIT合?用,則在msgsnd()執(zhí)?行時若是消息隊列已滿,則msgsnd()將不會阻塞,?而 會?立即返回-1,如果執(zhí)?行的是msgrcv(),則在消息隊列呈空時,不做等待馬上返回-1,并設定 錯誤碼為ENOMSG。當msgflg為0時,msgsnd()及msgrcv()在隊列呈滿或呈空的情形時,采取 阻塞等待的處理模式。 3.設置消息隊列屬性 原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf ); 參數(shù):msgctl 系統(tǒng)調?用對 msgqid 標識的消息隊列執(zhí)?行 cmd 操作,系統(tǒng)定義了 3 種 cmd 操作 : IPC_STAT , IPC_SET , IPC_RMID IPC_STAT : 該命令?用來獲取消息隊列對應的 msqid_ds 數(shù)據(jù)結構,并將其保存到 buf 指 定的地址空間。 IPC_SET : 該命令?用來設置消息隊列的屬性,要設置的屬性存儲在buf中。 IPC_RMID : 從內核中刪除 msqid 標識的消息隊列。
簡單示例: 我們創(chuàng)建2個進程,進程A創(chuàng)建消息隊列并發(fā)送消息,給進程B,之后進程B給進程A發(fā)消息。 代碼如下:
head.h:#ifndef _HEAD_#define _HEAD_#include<iostream>#include<stdio.h>#include<stdlib.h>#include<sys/ipc.h>#include<sys/msg.h>#include<sys/types.h>#include<string.h>#include<time.h>#define MY_SIZE 100#define _PATH "."http://默認路徑為當前目錄using namespace std;typedef struct msgstru{ long mtype; char str[MY_SIZE];}msgstru;(自己定義的msgstru)int my_mssgget(const char *str);(這里做了一層封裝)#endif--------------------------------------------head.c:#include"head.h"int my_mssgget(const char *str){ key_t key = ftok(str, 666);//獲取一個key值 return msgget(key, IPC_CREAT|IPC_EXCL|0666);}-----------------------------------------------程序A,read.c:#include"2-16.h"int main(){ char str[MY_SIZE]; msgstru A; A.mtype = 1; int msqid = my_mssgget(_PATH); int i = 3; while(i >= 1){ ssize_t pos = read(0,A.str, MY_SIZE/2); (A.str)[pos-1] = 0; if ( msgsnd(msqid,&(A.str), pos, 0) == -1){ perror("write error"); exit(0); } i--; }新聞熱點
疑難解答