1. 建立/擷取一個消息隊列
參數:
name: 消息隊列名字;
oflag: 與open函數類型, 可以是O_RDONLY, O_WRONLY, O_RDWR, 還可以按位或上O_CREAT, O_EXCL, O_NONBLOCK.
mode: 如果oflag指定了O_CREAT, 需要指定mode參數;
attr: 指定消息隊列的屬性;
傳回值:
成功: 傳回消息隊列檔案描述符;
失敗: 傳回-1;
注意-Posix IPC名字限制:
1. 必須以”/”開頭, 并且後面不能還有”/”, 形如:/file-name;
2. 名字長度不能超過NAME_MAX
3. 連結時:Link with -lrt.
/** System V 消息隊列
通過msgget來建立/打開消息隊列
int msgget(key_t key, int msgflg);
**/
2. 關閉一個消息隊列
3. 删除一個消息隊列
4. 擷取/設定消息隊列屬性
newattr: 需要設定的屬性
oldattr: 原來的屬性
通過msgctl函數, 并将cmd指定為IPC_STAT/IPC_SET來實作
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
5. 發送消息
msg_ptr: 指向需要發送的消息的指針
msg_len: 消息長度
msg_prio: 消息的優先級
通過msgsnd函數來實作消息發送
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
6. 從消息隊列中讀取消息
msg_len: 讀取的消息的長度, 注意: 此值一定要等于mq_attr::mq_msgsize的值, 該值可以通過mq_getattr擷取, 但一般是8192位元組 [this must be greater than the mq_msgsize attribute of the queue (see mq_getattr(3)).]
msg_prio: 儲存擷取的消息的優先級
成功: 傳回讀取的消息的位元組數
失敗: 傳回-1
注意: 讀取的永遠是消息隊列中優先級最高的最早的消息, 如果消息隊列為, 如果不指定為非阻塞模式, 則mq_receive會阻塞;
通過msgrcv函數來實作消息發送的
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
7. 建立/删除消息到達通知事件
參數sevp:
NULL: 表示撤銷已注冊通知;
非空: 表示當消息到達且消息隊列目前為空, 那麼将得到通知;
通知方式:
1. 産生一個信号, 需要自己綁定
2. 建立一個線程, 執行指定的函數
注意: 這種注冊的方式隻是在消息隊列從空到非空時才産生消息通知事件, 而且這種注冊方式是一次性的!
sigev_notify代表通知的方式: 一般常用兩種取值:SIGEV_SIGNAL, 以信号方式通知; SIGEV_THREAD, 以線程方式通知
如果以信号方式通知: 則需要設定一下兩個參數:
sigev_signo: 信号的代碼
sigev_value: 信号的附加資料(實時信号)
如果以線程方式通知: 則需要設定以下兩個參數:
sigev_notify_function
sigev_notify_attributes
/** Posix IPC所特有的功能, System V沒有 **/
mq_notify 注意點總結:
1. 任何時刻隻能有一個程序可以被注冊為接收某個給定隊列的通知;
2. 當有一個消息到達某個先前為空的隊列, 而且已有一個程序被注冊為接收該隊列的通知時, 隻有沒有任何線程阻塞在該隊列的mq_receive調用的前提下, 通知才會發出;
3. 當通知被發送給它的注冊程序時, 該程序的注冊被撤銷. 程序必須再次調用mq_notify以重新注冊(如果需要的話),但是要注意: 重新注冊要放在從消息隊列讀出消息之前而不是之後(如同示例程式);
附-檢視已經成功建立的Posix消息隊列
#其存在與一個虛拟檔案系統中, 需要将其挂載到系統中才能檢視
Mounting the message queue filesystem On Linux, message queues are created in a virtual filesystem.
(Other implementations may also provide such a feature, but the details are likely to differ.) This
file system can be mounted (by the superuser, 注意是使用root使用者才能成功) using the following commands:
mkdir /dev/mqueue
mount -t mqueue none /dev/mqueue
還可以使用cat檢視該消息隊列的狀态, rm删除:
cat /dev/mqueue/abc
rm abc
還可umount該檔案系統
umount /dev/mqueue
附-Makefile