歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> POSIX 和 System V 消息隊列!涉及到的函數總結!(基礎篇)

POSIX 和 System V 消息隊列!涉及到的函數總結!(基礎篇)

日期:2017/2/28 16:05:19   编辑:Linux教程

消息隊列(也叫做報文隊列)能夠克服早期unix通信機制的一些缺點。信號這種通信方式更像"即時"的通信方式,它要求接受信號的進程在某個時間范圍內對信號做出反應,因此該信號最多在接受信號進程的生命周期內才有意義,信號所傳遞的信息是接近於隨進程持續的概念(process-persistent);管道及有名管道則是典型的隨進程持續IPC,並且,只能傳送無格式的字節流無疑會給應用程序開發帶來不便,另外,它的緩沖區大小也受到限制

  消息隊列就是一個消息的鏈表。可以把消息看作一個記錄,具有特定的格式以及特定的優先級。對消息隊列有寫權限的進程可以向中按照一定的規則添加新消息;對消息隊列有讀權限的進程則可以從消息隊列中讀走消息。消息隊列是隨內核持續的。

POSIX 消息隊列的函數:
1. mq_open 創建一個新的消息隊列或者打開一個已經從存在的消息隊列!
#include<mqueue.h>
mqd_t mq_open(const char *name,int oflag,)
這個函數成則返回消息隊列的描述符,出錯則返回-1;在創建一個新的消息隊列時後面的2個參數是需要的,其中第4個參數 attr 用來給新隊列指定某寫屬性!若為NULL 則采用默認屬性!第3個參數 mode 用來設置 主 組 和其他成員 的讀寫權限!
mq_close:關閉已經打開的消息隊列!int mq_close(mqd_t mqdes);該函數只是釋放掉來文件描述符!要從內存中刪除消息隊列要用mq_unlink()函數!int mq_unlink(const char *name)!
2. mq_getattr 和 mq_setattr 函數:
每個消息隊列有四個屬性,mq_getattr 用來返回這些屬性! mq_setattr 用來設置其中的某個屬性!
#inlcude <mqueue.h>
int mq_getattr(mqd_t mqdes ,struct mq_attr *attr)
int mq_setattr(mqd_t mqdes,const struct mq_attr *attr,struct mq_attr *oattr)
成功返回0,失敗返回-1;
struct mq_attr
{
long mq_flags;
long mq_maxmsg;
long mq_msgsize;
long mq_curmsgs;
}
3.mq_send 和 mq_receive 函數
往隊列中放一個消息 和從 消息隊列中去走一個消息!
#include <mqueue.h>
int mq_send (mqd_t mqdes, const char *ptr , size_t len, unsigned int prio);
int mq_receive (mqd_t mqdes, const char *ptr , size_t len, unsigned int *prio)

System V 消息隊列:
使用消息隊列描述符標示:有足夠特權的任何進程可以讀 或 寫一個消息隊列!
對於系統的每個消息隊列,內核維護一個定義在<sys/msg.h> 的結構:
struct msqid_ds{
.
.
.
}
其中包括了一個結構體:struct ipc_perm {
....
}
這個結構體保存消息隊列的重要屬性,比如消息隊列的鍵值,消息隊列的用戶組ID ,組ID 定義在頭 linux/ipc.h 中;這些東西就是msgget 中 oflag 的讀寫權限位存放在 msg_perm.mode 中!



1.msgget 函數
#include <sys/msg.h>
int msgget (key_t key,int oflag)
其中 key 可以通過 ftok 和 IPC_PRIVATE 設定!

ftok函數 (IPC_PRIVATE自動產生一個鍵值)

系統建立IPC通訊(如消息隊列、共享內存時)必須指定一個ID值。通常情況下,該id值通過ftok函數得到。
ftok原型如下:
key_t ftok( char * fname, int id )
fname就時你指定的文件名,id是子序號。

在一般的UNIX實現中,是將文件的索引節點號取出,前面加上子序號得到key_t的返回值。

如指定文件的索引節點號為65538,換算成16進制為0x010002,而你指定的ID值為38,換算成16進制為0x26,則最後的key_t返回值為0x26010002。
查詢文件索引節點號的方法是: ls -i
測試小程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>

#define IPCKEY 0x11
int main( void )
{
int i=0;
for ( i = 1; i < 256; ++ i )
printf( "key = %x\n", ftok( "/tmp", i ) );

return 0;
}
當刪除重建文件後,索引節點號由操作系統根據當時文件系統的使用情況分配,因此與原來不同,所以得到的索引節點號也不同。


2.msgsnd 和 msgrcv 函數:
#include <sys/msg.h>
int msgsnd (int msqid, const void *ptr , size_t length , int flag);
成功返回0 失敗返回-1;
ssize_t msgrcv (int msqid,void *ptr,size_t length, long type,int flag);
成功返回 讀入緩存區的數據字節,出錯返回 -1;
其中 ptr 是結構題指針;
struct msgbuf
{
long mtype;
char mtext[1];
}

3. msgctl 函數:
#include <sys/msg.h>
int msgctl (int msgid,int cmd, struct msqid_ds *buff);
在消息隊列上的操作!
Copyright © Linux教程網 All Rights Reserved