UNIX環境下如何應用訊息佇列實現程序間通訊

2021-03-31 14:34:22 字數 4836 閱讀 7665

一、引言

----進入九十年代後,隨著計算機和網路技術的發展,很多資料處理系統都採用開放系統結構的客戶機/伺服器網路模式。即客戶機提出任務請求,由伺服器做相應處理,執行被請求的任務,然後將結果返回給客戶機。例如:銀行atm的前置機和資料處理的主機之間即構成客戶機/伺服器模式;**銀行的前置機和銀行資料處理主機之間也構成這種模式結構。還有pos等。這樣,各種應用的請求是很頻繁的,資料主機在處理通存通兌,atm,**銀行,pos等各種請求時,如果沒有相應機制的控制,資料將出現混亂,有可能產生透支,也有可能處理密碼已改變的帳戶.。資料的完整性,安全性無法控制。而訊息佇列正是解決這一問題的有力工具。它使主機在處理各種請求時,按照先後順序有條不紊地進行,保證了資料的一致性和安全性。

二、基本概念

----1.佇列

----佇列是資訊的線性表,它的訪問次序是先進先出(fifo)。也就是說,置入佇列中的第乙個資料項將是從佇列中第一次讀出的資料項,置入的第二項將是讀出的第二項,依此類推。這是佇列允許的唯一訪問操作,其它隨機訪問是不允許的。這種資料結構保證對資料資源的請求將嚴格按照先後順序進行,因而可用於對事件的排程並起到i/o緩衝的作用。

----2.報文

----傳送程序和接收程序進行資訊的交換,一般是通過將資訊劃分為若干段放入資料交換緩衝器中,程序間通過對該緩衝器的訪問來實現通訊。因此,資料是以不連續的形式在程序間傳送,這些不連續的部分就叫報文。

----3.訊息佇列

----將報文按佇列的結構進行組織就叫訊息佇列。該佇列用於存放正被傳送或接收的每乙個報文的標題資訊。每乙個訊息佇列還對應有乙個資料結構,它含有訊息佇列的訪問許可權,和訊息佇列的當前狀態資訊等資訊。訊息佇列可進行"傳送"和"接收"操作。

三、訊息佇列的程式設計要點及運作過程

----1.訊息佇列的建立

----在報文能夠傳送和接收之前,必須建立乙個能夠唯一被識別出的訊息佇列和資料結構,這個被建立的唯一識別符號叫做訊息佇列描述符(msqid),用來識別或引用相關的訊息佇列和資料結構。用msgget(longkey,intmsg***)系統呼叫來建立訊息佇列,其中key是乙個長整型,可由使用者設定也可通過ftok()獲得。msg***的值是八進位制的訊息佇列操作權和控制命令的組合。操作權定義為:

操作允許權八進位制整數

使用者可讀0400

使用者可寫0200

同組可讀0040

同組可寫0020

其它可讀0004

其它可寫0002

----操作權可相加而派生,如使用者可"讀"、"寫"的許可權為0400|0200=0600。控制命令可取ipc_creat或ipc_excl。如果要建立乙個key=888且屬主和同組可讀寫的訊息佇列,執行以下系統呼叫msgget(0x888,0660|ipc_creat)。建立後可用ipcs命令看到以下資訊:

ipcstatusfrom/dev/memasofsun

jan2506:49:521970

tidkeymodeownergroup

messagequeues:

.q70x00000888--rw-rw----

rootsystem

...----它的訊息佇列描述符是7,屬主是root,同組是system,訪問權是屬主、使用者可讀寫。如果執行msgget(0x888,0660|ipc_creat)時,與0x888對應的訊息佇列已存在,則返回該訊息佇列的描述符msqid。

----2.訊息的傳送

----訊息佇列一經建立即可用msgsnd(intmsqid,void*msgp,size_tmsgsz,intmsg***)傳送訊息。msgqid是經msgget建立的訊息佇列描述符,msgp是指向訊息段的指標,該指標所指結構含有報文型別和要傳送或接收的報文:

structmsgbuf

----msgsz是msgp參量指向的資料結構中字元陣列的長度,即報文長度,最大值由msgmax確定。msg***是當訊息佇列滿時(佇列中無空閒空間),系統要採取的行動.如果msg***&ipc_nowait=真,呼叫程序立即返回,不傳送該訊息。如果msg***&ipc_nowait=假,呼叫程序暫停執行,處於"掛起"狀態,且不傳送該訊息。直到下列情況之一出現:

-----引起暫停的條件不再存在,如佇列出現空閒,即可傳送

-----該消系佇列被從系統中刪去

-----呼叫程序接收到乙個要捕捉的訊號,如中斷訊號,此時不傳送訊息,呼叫程序按signal中描述的方式執行。

----如果msgsnd返回0則傳送成功。返回-1則表示傳送失敗,錯誤型別可具體檢視errno。

----3.訊息的接收

----用msgrcv(intmsqid,void*msgp,size_tmsgsz,longmsgtyp,intmsg***)系統呼叫從msqid訊息佇列中讀取一條資訊並將其放入訊息段指標msgp指向的結構。msgsz給出mtext的位元組數,如果所接收的訊息比msgsz大且msg***&msg_noerror為真,則按msgsz的大小截斷而不通知呼叫程序。msgtyp指定要求的訊息型別:

----msgtyp=0接收訊息佇列中的第乙個報文

----msgtyp>0接收訊息佇列中的型別為msgtyp的第乙個報文

----msgtyp<0接收訊息佇列中小於等於msgtyp絕對值的最低型別的第乙個報文

----當佇列上沒有所期望型別的訊息或訊息隊列為空時msg***指出呼叫程序要採取的行動:如果msg***&ipc_nowait為真,則呼叫程序立即結束並返回-1。如msg***&ipc_nowait為假,則呼叫程序暫停執行直至出現:

-----佇列中放入所需型別的訊息,呼叫程序接收該訊息

-----msqid訊息佇列從系統中刪除

-----呼叫程序接收到捕獲的訊號,此時不接收訊息,呼叫程序按signal描述的方式執行。

----如果msgrev執行成功,則返回放入mtext中的位元組數,失敗返回-1,錯誤型別可查errno。

----4.訊息佇列的控制和撤銷

----用msgctl(intmsqid,intcmd,structmsqid_ds*buf)系統呼叫實現對訊息佇列的控制。msgqid必須是用msgget建立的訊息佇列描述符。cmd可以是:

----ipc_stat檢視訊息佇列的狀態,結果放入buf指標指向的結構

----ipc_set為訊息佇列設定屬主標識,同組標識,操作允許權,最大位元組數

----ipc_rmid刪除指定的msqid以及相關的訊息佇列和結構

四、程式設計示例

----下面給出乙個運用訊息佇列,實現程序通訊的例項。以下程式在ibmrs/6000小型機(aix作業系統)上和ibmpc(unix作業系統)上分別除錯通過。該程式主要模擬根據帳號查詢餘額的過程。包括三方面:

請求程序從標準輸入讀入帳號,並將該帳號通過訊息佇列傳送給服務程序;

服務程序接收該帳號後,按照請求的先後順序在標準輸入上輸入該帳戶的姓名和餘額,並將結果返回給客戶程序;

請求程序接收返回的資訊,並將結果輸出在標準輸出上。

----服務程序(msgcenter)先於請求程序(msgreq)啟動.客戶程序啟動時要攜帶請求編號,可同時起動多個請求程序。

/*請求方程式msgreq.c*/

#include

#include

#include

#include

#include

static struct msgbuf1 sndbuf, rcvbuf, *msgp ;

extern int errno;

main(int argc, char **argv)

if ( (msqid = msgget(0x888, ipc_creat|0660)) == -1 )

msgp=&sndbuf;

sprintf(sndbuf.mtext,"%2.2s",argv[1]);

printf("輸入4位帳號:");

scanf("%s",&sndbuf.mtext[2]);

sndbuf.mtext[6]=0;

msgp->mtype=666;

rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0);

if (rtrn==-1)

msgp=&rcvbuf;

fprintf(stderr,"等待後台資料處理程序的回答....");

rtrn=msgrcv(msqid,msgp, 100, atoi(argv[1]), 0);

if(rtrn==-1)

sscanf(rcvbuf.mtext,"%[^|]|%lf",name,&balance);

printf("/n姓名=%s/n",name);

printf("餘額=%lf/n",balance);

}/*服務方程式msgcenter.c*/

#include

#include

#include

#include

#include

static struct msgbuf1 sndbuf, rcvbuf , *msgp;

extern int errno;

main()

while(1)

msgp=&sndbuf;

sprintf(strbuf,"%2.2s/0",rcvbuf.mtext);

msgp->mtype=atoi(strbuf);

printf("/n輸入帳號=%4.4s的帳戶姓名:",&rcvbuf.mtext[2]);

scanf("%s",sndbuf.mtext);

strcat(sndbuf.mtext,"|");

printf("輸入該帳戶餘額:");

scanf("%s",strbuf);

strcat(sndbuf.mtext,strbuf);

rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0);

if (rtrn==-1)}}

UNIX環境下如何應用訊息佇列實現程序間通訊

一 引言 進入九十年代後,隨著計算機和網路技術的發展,很多資料處理系統都採用開放系統結構的客戶機 伺服器網路模式。即客戶機提出任務請求,由伺服器做相應處理,執行被請求的任務,然後將結果返回給客戶機。例如 銀行atm的前置機和資料處理的主機之間即構成客戶機 伺服器模式 銀行的前置機和銀行資料處理主機之...

MQ訊息佇列應用

很榮幸,原來一直聽說的訊息佇列終於在前段時間用到了自己的專案中。為什麼會用到訊息佇列?毫無疑問,當然是傳輸訊息。這裡訊息一般是一串字串,當然,訊息的含義很多,可以是 hello world 可以是 你吃飯了嗎?可以是一串正式的xml報文。也可以是乙個txt檔案或者xml檔案 在用active mq的...

unix程序區訊息佇列學習筆記

unix系統中程序可以通過訊息進行通訊,訊息是格式化的可變長度的資訊單元,包含訊息型別 資料長度及資料三部分內容。每個訊息都有乙個唯一的名稱key,同時還有乙個唯一的訊息佇列描述符。訊息佇列的使用 1 建立 呼叫 int msgget intkey,int flags key為訊息佇列名稱,flag...