Linux IPC POSIX 消息队列
模型:
#include<mqueue.h> #include <sys/stat.h> #include <fcntl.h> mq_open() //創建/獲取消息隊列fd mq_get() //設置/獲取消息隊列屬性 mq_send()/mq_receive() //發送/接收消息 mq_close() //脫接消息隊列 mq_unlink() //刪除消息隊列POSIX mq VS Sys V mq的優勢
- 更簡單的基于文件的應用接口
- 完全支持消息優先級(優先級最終決動隊列中消息的位置)
- 完全支持消息到達的異步通知,這通過信號或是線程創建實現
- 用于阻塞發送與接收操作的超時機制
消息隊列名
由$man mq_overview知:消息隊列由一個形如'/somename'的名字唯一標識,名字字符串的最大長度不能朝著哦NAME_MAX(i.e.,255),兩個進程通過使用同一個消息隊列的名字來通信
mq_open()
//創建一個POSIX消息隊列或打開一個已經存在的消息隊列,成功返回消息隊列描述符mqdes供其他函數使用,失敗返回(mqd_t)-1設errno //Link with -lrt. mqd_t mq_open(const char *name, int oflag); mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);oflag
must include one of:
- O_RDONLY表示以只接收消息的形式打開消息隊列
- O_WRONLY表示以只發送消息的形式打開消息隊列
- O_RDWR表示以可接收可發送的形式打開消息隊列
can be Bitwised ORed:
- O_NONBLOCK以nonblocking的模式打開消息隊列
- O_CREAT如果一個消息隊列不存在就創建它,消息隊列的擁有者的UID被設為調用進程的effective UID,GID被設為調用進程的effective GID
- O_EXCL確保消息隊列被創建,如果消息隊列已經存在,則發生錯誤
mode如果oflag里有O_CREAT,則mode用來表示新創建的消息隊列的權限
attr如果oflag里有O_CREAT,則attr表示消息隊列的屬性,如果attr是NULL,則會按照默認設置配置消息隊列(mq_overview(7) for details.)
mq_setattr() / mq_getattr()
//設置/修改 / 獲取消息隊列屬性,成功返回0,失敗返回-1設errno //Link with -lrt. int mq_setattr(mqd_t mqdes, const struct mq_attr *newattr, struct mq_attr *oldattr); int mq_getattr(mqd_t mqdes, struct mq_attr *attr);mqattr結構體
struct mq_attr {long mq_flags; /* Flags: 0 or O_NONBLOCK */long mq_maxmsg; /* Max. # of messages on queue */long mq_msgsize; /* Max. message size (bytes) */long mq_curmsgs; /* # of messages currently in queue */ };mq_send() / mq_timesend()
//發送消息到mqdes指向的消息隊列。成功返回0,失敗返回-1設errno //Link with -lrt. int mq_send(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio);//如果消息隊列滿 #include<time.h> //額外的header int mq_timedsend(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio,const struct timespec *abs_timeout);msg_len msg_ptr指向的消息隊列的長度,這個長度必須<=消息隊列中消息長度,可以是0
msg_prio 一個用于表示消息優先級的非0整數,消息按照優先級遞減的順序被放置在消息隊列中,同樣優先級的消息,新的消息在老的之后,如果消息隊列滿了,就進入blocked狀態,新的消息必須等到消息隊列有空間了進入,或者調用被signal中斷了。如果flag里有O_NOBLOCK選項,則此時會直接報錯
abs_timeout:如果消息隊列滿了,那么就根據abs_timeout指向的結構體表明的時間進行鎖定,里面的時間是從970-01-01 00:00:00 +0000 (UTC)開始按微秒計量的時間,如果時間到了,那么mq_timesend()立即返回
mq_receive()/mq_timedreceive()
//從消息隊列中取出優先級最高的里面的最老的消息,成功返回消息取出消息的大小,失敗返回-1設errno //具體功能參照mq_send()/mq_timesend() //Link with -lrt. ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); #include<time.h> //額外的header ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout);mq_notify()
//允許調用進程注冊或去注冊同步來消息的通知,成功返回0,失敗返回-1設errno //Link with -lrt. int mq_notify(mqd_t mqdes, const struct sigevent *sevp);sevp指向sigevent的指針
- 如果sevp不是NULL,那么這個函數就將調用進程注冊到通知進程,只有一個進程可以被注冊為通知進程
- 如果sevp是NULL且當前進程已經被注冊過了,則去注冊,以便其他進程注冊
sigev_notify使用下列的宏進行配置:
- SIGEV_NONE調用進程仍舊被注冊,但是有消息來的時候什么都不通知
- SIGEV_SIGNAL通過給調用進程發送sigev_signo指定的信號來通知進程有消息來了
- SIGEV_THREAD一旦有消息到了,就激活sigev_notify_function作為新的線程的啟動函數
mq_close()
//關閉消息隊列描述符mqdes,如果有進程存在針對這個隊列的notification request,那么也會被移除 //成功返回0,失敗返回-1設errno //Link with -lrt. int mq_close(mqd_t mqdes);mq_unlink():
//移除隊列名指定的消息隊列,一旦最后一個進程關閉了針對這個消息隊列的描述符,就會銷毀這個消息隊列 //成功返回0,失敗返回-1設errno //Link with -lrt. int mq_unlink(const char *name);總結
以上是生活随笔為你收集整理的Linux IPC POSIX 消息队列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2016第18本:世界上最简单的会计书
- 下一篇: springMVC--(讲解5)文件上传