linux下的消息隊列編程_第1頁
linux下的消息隊列編程_第2頁
linux下的消息隊列編程_第3頁
linux下的消息隊列編程_第4頁
linux下的消息隊列編程_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、Linux 下的消息隊列的使用SUNNY.MAN一、消息隊列的基本概念消息隊列(也叫做報文隊列)是 Unix 系統(tǒng) V 版本中進程間通信機制之一。消息隊列就是一個消息的鏈表。就是把消息看作一個記錄,并且這個記錄具有特定的格式以及特定的優(yōu)先級。對消息隊列有寫權(quán)限的進程可以按照一定的規(guī)則添加新消息;對消息隊列有讀權(quán)限的進程則可以從消息隊列中讀出消息。Linux 采用消息隊列的方式來實現(xiàn)消息傳遞。這種消息的發(fā)送方式是:發(fā)送方不必等待接收方檢查它所收到的消息就可以繼續(xù)工作下去,而接收方如果沒有收到消息也不需等待。新的消息總是放在隊列的末尾,接收的時候并不總是從頭來接收,可以從中間來接收。消息隊列是隨內(nèi)

2、核持續(xù)的并和進程相關(guān),只有在內(nèi)核重起或者顯示刪除一個消息隊列時,該消息隊列才會真正被刪除。因此系統(tǒng)中記錄消息隊列的數(shù)據(jù)結(jié)構(gòu)(structipc_idsmsg_ids)位于內(nèi)核中,系統(tǒng)中的所有消息隊列都可以在結(jié)構(gòu)msg_ids 中中找到訪問入口。IPC 標(biāo)識符:每一個 IPC 目標(biāo)都有一個唯一的 IPC 標(biāo)識符。這里所指的 IPC 目標(biāo)是指一個單獨的消息隊列、一個信號量集或者一個共享的內(nèi)存段。系統(tǒng)內(nèi)核使用此標(biāo)識符在系統(tǒng)內(nèi)核中指明 IPC 目標(biāo)。IPC 關(guān)鍵字:想要獲得唯一的標(biāo)識符,則必須使用一個 IPC 關(guān)鍵字。客戶端進程和服務(wù)器端進程必須雙方都同意此關(guān)鍵字。這是建立一個客戶機/服務(wù)器框架的第一

3、步。一般情況下,可以使用 ftok()函數(shù)為客戶端和服務(wù)器端產(chǎn)生關(guān)鍵字值。#include#includekey_tftok(constchar*fname,intid)fname 就是你指定的文件名(已經(jīng)存在的文件名),一般使用當(dāng)前目錄,如:key_tkey;key=ftok(.,1);這樣就是將 fname 設(shè)為當(dāng)前目錄。id 是子序號在一般的 UNIX 實現(xiàn)中,是將文件的索引節(jié)點號取出, 前面加上子序號得到 key_t 的返回值。 如指定文件的索引節(jié)點號為65538,換算成 16 進制為 0 x010002,而你指定的 ID 值為 38,換算成 16 進制為 0 x26,則最后的 key

4、_t 返回值為 0 x26010002。查詢文件索引節(jié)點號的方法是:ls-i 當(dāng)刪除重建文件后,索引節(jié)點號由操作系統(tǒng)根據(jù)當(dāng)時文件系統(tǒng)的使用情況分配,因此與原來不同,所以得到的索引節(jié)點號也不同。如果要確保 key_t 值不變,要么確保 ftok 的文件不被刪除,要么不用 ftok,指定一個固定的 key_t 值,比如:#defineIPCKEY0 x111charpath256;sprintf(path,%s/etc/config.ini,(char*)getenv(HOME);msgid=ftok(path,IPCKEY);也就是說其實 ftok 的作用就是根據(jù)你所指定的文件的索引點號生成一個

5、獨一無二的KEY,并保持。不過在使用的過程中,一般都是直接指定一個固定的值,這樣使用起來簡單,但一定要確保和其它程序不沖突。二、使用消息隊列查看一個系統(tǒng)中的消息可以用 ipcs-q 來查看,這可以看到 msgid 和權(quán)限以及當(dāng)前有幾條消息。當(dāng)你在調(diào)試的過程中,由于程序沒有正常結(jié)束,而你又想刪除此消息時,請使用 ipcrm-qmsgid 命令。下面結(jié)合具體的實例代碼詳細(xì)說明一下使用的過程。Snd.c 文件#include#include#include#include#include#include#include#defineMAX_TEXT512#defineMSG_KEY335struct

6、my_msg_stlongmy_msg_type;/這個就是消息的類型,在接收的時候一定要指定這個/類型才會接收到相應(yīng)的消息。charsome_textMAX_TEXT;intmain()inti=10;intrunning=1;structmy_msg_stsome_data;intmsgid;charbufferBUFSIZ;msgid=msgget(key_t)MSG_KEY,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);首先創(chuàng)建,如果不成功,就取得if(msgid=-1)printf(createfailegetimsgidn);msgid=msgget(ke

7、y_t)MSG_KEY,IPC_EXCL|S_IRUSR|S_IWUSR);if(msgid=-1)fprintf(stderr,msggetfailedwitherror:%dn,errno);exit(EXIT_FAILURE);while(running)(printf(%dEntersometext:lessthan%dn,msgid,MAX_TEXT);fgets(buffer,BUFSIZ,stdin);some_data.my_msg_type=10;strcpy(some_data.some_text,buffer);if(msgsnd(msgid,(void*)&so

8、me_data,sizeof(some_data),0)=-1)(fprintf(stderr,msgsndfailedn);exit(EXIT_FAILURE);if(strncmp(buffer,end,3)=0)(running=0;exit(EXIT_SUCCESS);Rcv.c 文件#include#include#include#include#include#include#include#include#defineMAX_TEXT512#defineMSG_KEY335structmy_msg_st(longmy_msg_type;charsome_textMAX_TEXT;

9、intmain()(intrunning=1;intmsgid;structmy_msg_stsome_data;longintmsg_to_receive=10;msgid=msgget(key_t)MSG_KEY,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);if(msgid=-1)msgid=msgget(key_t)MSG_KEY,IPC_EXCL|S_IRUSR|S_IWUSR);if(msgid=-1)fprintf(stderr,msggetfailedwitherror:%dn,errno);exit(EXIT_FAILURE);printf(prep

10、arereceivemsg:%dn,msgid);while(running)/這里的 msg_to_receive 指定了接收消息的類型,如果類型不對,將取不到消息.IPC_NOWAIT 果消息隊列里沒有消息,則馬上返回并設(shè)置 errno=ENOMSG 如果指定為 0 則將等待消息的到來。if(msgrcv(msgid,(void*)&some_data,sizeof(some_data),msg_to_receive,IPC_NOWAIT)=-1)if(ENOMSG=errno)printf(noMsgreceiven);continue;fprintf(stderr,msgrcv

11、failedwitherror:%dn,errno);exit(EXIT_FAILURE);printf(Youwrote:%s,some_data.some_text);if(strncmp(some_data.some_text,end,3)=0)running=0;if(msgctl(msgid,IPC_RMID,0)=-1)/使用這個庫函數(shù)來移除消息隊列。fprintf(stderr,msgctl(IPC_RMID)failedn);exit(EXIT_FAILURE);exit(EXIT_SUCCESS);.三、消息隊列的相關(guān)參數(shù)1.查看系統(tǒng)中默認(rèn)的消息隊列的相關(guān)參數(shù)IpcsT 可以

12、查看當(dāng)前消息隊列的上限限制。Messages:Limitsmaxqueuessystemwide=162Gmaxsizeofmessage(bytes)=655362Gdefaultmaxsizeofqueue(bytes)=655362Gmsgmni 最大消息隊列數(shù)msgmax 最大消息長度(字節(jié)數(shù))msgmnb 消息隊列中的最大字節(jié)數(shù)其實我們要關(guān)心的參數(shù)主要有三個,說得通俗點就是最多可以有多少個隊列使用,每個隊列里可以放多少消息,每個消息最多可以帶多少內(nèi)容?,F(xiàn)在解釋如下:系統(tǒng)中默認(rèn)的消息列數(shù)是 16,最大可以達(dá)到 2G,系統(tǒng)中消息的個數(shù)和消息長度的總數(shù),受隊列最大尺寸限制。Msgmnb=m

13、sgmax*最大個數(shù).其中消息隊列的長度受結(jié)構(gòu)使用。structmy_msg_stlongmy_msg_type;charsome_textMAX_TEXT;大家如果有興趣,可以自己寫個程序測試試下,簡單的很就是無限制分配就可以了。修改消息隊列的參數(shù)1 .永久修改root 用戶下修改/etc/sysctl.conf 文件。2 .臨時修改root 用戶下 sysctl-wkernel.msgmnb=1048576/proc/sys/kernel/msgmax 單個消息的最大值/proc/sys/kernel/msgmnb 單個消息體的容量的最大值/proc/sys/kernel/msgmni 消

14、息體的數(shù)量缺省值為 16cat/proc/sys/kernel/shmmax可通過下面的方式進行設(shè)置echo819200/proc/sys/kernel/msgmaxecho1638400/proc/sys/kernel/msgmnbecho1600/proc/sys/kernel/msgmnicd/proc/sys/kernel;catmsgmax;catmsgmnb;catmsgmni;在程序中可以通過msgctl(msgid,IPC_STAT,&mymsq_ds);printf(%d,%d,%dn”,mymsq_ds.msg_qbytes,mymsq_ds.msg_qnum,mymsq_ds.msg_cbytes);來獲得隊列消息的總大小,已經(jīng)有的消

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論