和訊號相比,資訊佇列是隨核心持續的,而訊號是隨程序持續的,管道和有名管道也是隨程序持續的。訊息佇列是乙個訊息的鍊錶,可以將訊息看作乙個記錄,具有特定的格式和特定的優先順序。 對訊息佇列有寫許可權的程序可以向訊息佇列中按照一定的規則新增新的訊息;對訊息佇列又讀許可權的程序則可以從訊息佇列中讀走資訊。目前主要有兩者型別的訊息佇列:posix訊息佇列和系統v訊息佇列。系統v訊息佇列相對來說應用更加廣泛,但是考慮到程式的可一致性,還是應盡量開發posix訊息佇列。
本文旨在介紹系統v訊息佇列的一些常用api。
訊息佇列api函式及其用途:
msgget : 建立乙個新的訊息佇列 或者 獲取訊息佇列的id
msgsnd : 向訊息佇列傳送訊息
msgrcv : 從訊息佇列讀取訊息
msgctl : 獲取訊息佇列的資訊 or 設定訊息佇列的資訊 or 移除訊息佇列。
1,
int ftok(char *pathname, char proj)
pathname : 訊息佇列的檔案路徑 ;
proj : 一般取值為:『a』
2,
int msgget( key_t key , int msgflag )
key 為ftok函式的返回值,也可以為ipc_private指不提供鍵值
msgflag : 允許使用者設定兩者型別的引數,乙個指令和乙個訪問許可權設定,訪問許可權的設定和設定檔案的訪問許可權的方式一樣。
指令的設定可以設定為:ipc_creat(建立乙個訊息佇列),ipc_excl(判斷訊息佇列是否已經存在,如果存在
就返回乙個錯誤資訊),0(告訴msgget訊息佇列已經存在,任務是獲取訊息佇列的描述符)
看下面的兩個msgget的兩個應用的例子:
samp1 : 獲得訊息佇列的描述符:
// get the description of message queue
msgid = msgget( key , 0 );
if(msgid == -1)
samp2 :建立乙個新的訊息佇列:
// create a new message queue
msgid = msgget(key , ipc_creat | ipc_excl | 0666); //設定訪問許可權和判斷是否存在
if(msgid == -1)
else
3,
#includeint msgctl( int msgid , int cmd , struct msqid_ds *buf) ;
主要有三個功能:
fun 1 :
//移除訊息佇列
int msgid , ret ;
msgid = msgget( key , 0);
if( msgid != -1)
}
fun 2 :
//設定訊息佇列的屬性
int msgid, ret ;
struct msqid_ds buf ;
msgid = msgget( key , 0 );
ret = msgctl(msgid, ipc_stat ,&buf);
if( ret == -1)
else
buf.msg_qbytes = 20000 ;
ret = msgctl(msgid , ipc_set , &buf);
if(ret == -1)
else
4,
int msgsnd( int msgid , struct msgbuf *msgp , size_t msgsz , int msgflag) ;
msgp : 乙個struct msgbuf結構體,存放要向訊息佇列中傳送的內容。
msgsz : msgbuf 的大小。
msgflag : ipc_nowait向訊息佇列中傳送內容的時候,如果沒有足夠的空間不阻塞,立即返回。
5.
int msgrcv( int msgid , struct msgbuf *msgp , size_t msgsz , long msgtyp, int msgflag)
前面三個引數和msgsnd一樣。
msgtyp : 0 讀取訊息佇列中可用的第一條資訊
>0 指定要讀取的訊息的type
<0 返回訊息佇列中的第一條訊息型別號小於或等於msgtyp的絕對值的訊息
msgflag : ipc_nowait: 如果訊息佇列中沒有msgtyp的訊息,立即返回,不阻斷
msg_execpt:返回除msgtyp指定型別以外的第一條訊息
msg_noerror:如果使用者的緩衝區不夠大,直接截去訊息中儲存不下的部分。
/*
訊息佇列例項
*/#include#include#include#include#include#include#include#include#include#define max_line 80
struct msqid_ds buf ;
/*定義訊息的結構*/
typedef structmsg_type ;
int
main(int argc,char *argv)
msgid = msgget(key,ipc_creat|ipc_excl|0666); /* 建立乙個訊息佇列,並設定許可權*/
if(msgid == -1)
ret = msgctl(msgid, ipc_stat,&buf); /* 獲得訊息佇列隊頭,即訊息佇列自身的資訊 */
if(ret == -1)
/* 定義需要寫入的資訊 */
my_type.mtype = 1l ;
my_type.fval = 128.1256 ;
my_type.uival = 1291223 ;
strncpy(my_type.strval,"this is message queue!\n",max_line);
ret = msgsnd(msgid , (msg_type *)&my_type,sizeof(msg_type),0); /* 向訊息佇列中寫入內容 */
if(ret == -1)
printf("write success!\n"); /* 寫入訊息成功 */
ret = msgctl(msgid,ipc_stat,&buf); /* 獲得訊息佇列的資訊。 */
assert(ret != -1);
printf("current number of bytes on queue:%ld\n",buf.msg_cbytes); /* 訊息佇列的儲存量 */
printf("number of message in queue is : %ld\n",buf.msg_qnum); /* 訊息佇列中訊息的條數 */
printf("max number of bytes on queue is : %ld\n",buf.msg_qbytes); /* 訊息佇列的最大儲存量*/
printf("\n");
ret = msgrcv(msgid, (msg_type *)&my_type, sizeof(msg_type),0,0); /*讀取訊息佇列中的資訊。*/
assert( ret!=-1 ) ;
printf("message type : %ld\n",my_type.mtype);
printf("float value: %f\n",my_type.fval);
printf("uint val is : %d\n",my_type.uival);
printf("string val is : %s\n",my_type.strval);
ret = msgctl(msgid,ipc_rmid,null); /*訊息佇列的撤銷*/
assert( ret!=-1 );
printf("queue %d successfully removed!\n",msgid);
return 0;
}
檢視當前程序可見的所有訊息佇列: # ipcs -q
檢視具體某個訊息佇列id的資訊: # ipcs - q -i queue_num
刪除某個訊息佇列: # ipcrm -q queue_num
linux訊息佇列 Linux訊息佇列
訊息佇列,unix的通訊機制之一,可以理解為是乙個存放訊息 資料 容器。將訊息寫入訊息佇列,然後再從訊息佇列中取訊息,一般來說是先進先出的順序。可以解決兩個程序的讀寫速度不同 處理資料速度不同 系統耦合等問題,而且訊息佇列裡的訊息哪怕程序崩潰了也不會消失。最簡單的訊息記憶體的使用流程 ftok函式生...
linux訊息佇列
訊息佇列是核心位址空間中的內部鍊錶,每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得乙個訊息佇列的描述字,只需提供該訊息佇列的鍵值即可。1 訊息緩衝區結構 存放訊息資料的模板,可在基本定義的基礎上自己定義 在include linux msg.h中宣告,描述如下 struct 可以定義自己的例...
linux 訊息佇列
一 訊息佇列的基本概念 訊息佇列 也叫做報文佇列 是unix系統v版本中3種程序間通訊機制之一。另外兩種是訊號燈和共享記憶體。這些ipc機制使用共同的授權方法。只有通過系統呼叫將標誌符傳遞給核心之後,程序才能訪問這些資源。這種系統ipc物件使用的控制方法和檔案系統非常類似。使用物件的引用標誌符作為資...