消息隊列基礎

###消息隊列基礎
    ##消息隊列
        比喻:回轉壽司、按優先級進行(讓列寧同志先走)
        本質:內核鏈表
    
    ##POSIX消息隊列
        接口
            頭文件:mqueue.h
            庫: rt librt.so    real time
            結構體: struct mq_attr
                消息隊列屬性
                        mq_flags【標誌】:
                            在mq_open時被初始化;在mq_setattr設置;其值爲0或者O_NONBLOCK;
                mq_maxmsg【隊列的消息個數最大值】:
                    只能在mq_open時被初始化
                mq_msgsize【隊列每個消息的最大值】:
                    只能在mq_open時被初始化
                mq_curmsgs【當前隊列消息長度】:
                    在mq_getattr獲取
        函數【八大操作】
            創建消息隊列:mqd_t mq_open(const char *name,int oflag,mode_t mode,struct mq_attr* attr);
                name:posix IPC名字
                oflag:標誌:O_CREAT【沒有該對象則創建】、O_EXCL【如果O_CREAT指定,但name不存在,就返回錯誤】、O_NONBLOCK【以非阻塞方式打開消息隊列】、O_RDONLY【只讀】、O_RDWR【讀寫】、O_WRONLY【只寫】
                mode:權限:S_IWUSR【用戶/屬主寫】、S_IRUSR【用戶/屬主讀】、S_IWGRP【組成員寫】、S_IRGRP【組成員讀】、S_IWOTH【其他用戶寫】、S_IROTH【其他用戶讀】
                attr:隊列屬性:【阻塞】attr.mq_flag =  0;【非阻塞】attr.mq_flag = NONBLOCK
                返回值:-1【出錯】、其他【消息隊列描述符】
            刪除消息隊列:int mq_unlink(const char* name);
                name:posix IPC名字
                返回值:-1【出錯】、0【成功】
            打開消息隊列:mqd_t mq_open(const char* name,int oflag);
                name:posix IPC名字
                oflag:標誌:【只讀】O_RDONLY、【讀寫】O_RDWR、【只寫】O_WRONLY
                返回值:-1【出錯】、其他【描述符】
            關閉消息隊列:int mq_close(mqd_t mqdes,struct mq_attr,*newattr,struct mq_attr *oldattr);
                mqdes:消息隊列描述符
                newattr:新屬性;只設置mq_flags{0;NONBLOCK}
                oldattr:舊屬性
                返回值:-1【出錯】、0【成功】
            獲取消息隊列屬性:int mq_getattr(mqd_t mqdes,struct mq_attr *attr);
                mqdes:消息隊列描述符
                attr:屬性
                返回值:-1【出錯】、0【成功】
            發送消息:int mq_send(mqd_t mqdes,const char *msg_ptr,size_t msg_len,unsigned msg_prio);
                msg_ptr:消息的指針
                msg_len:消息長度【不能大於屬性值mq_msgsize的值】
                msg_prio:優先級【消息在隊列中將按照優先級大小順序來排列消息】
**消息隊列已滿,mq_send()函數將阻塞,直到有可用空間再次允許放置消息;如果O_NONBLOCK被指定,mq_send()那麼將不會阻塞,而是返回EAGAIN錯誤
            接收消息:ssize_t mq_receive(mqd_t mqdes,char* msg_ptr,size_t msg_len,unsigned *msg_prio);
                msg_ptr:消息的指針
                msg_len:消息長度【不能大於屬性值mq_msgsize的值】
                msg_prio:優先級【消息在隊列中將按照優先級大小順序來排列消息】
                返回值:-1【出錯】、正數【接收到的消息長度】
**如果隊列空,mq_recieve()函數將阻塞,直到消息隊列中有新的消息;如果O_NONBLOCK被指定,mq_receive()那麼將不會阻塞,而是返回EAGAIN錯誤
        查看
            man mq_overview
            ls /dev/mqueue
            cat /dev/mqueue/PIC名字
    ##System V消息隊列
        接口
            頭文件:sys/msg.h
            結構體:自定義消息緩衝區結構msgbuf
                mtype【消息類型】:必須是long;必須是結構體第一個變量
                mtext【消息數據】:可以隨意定義
            函數
                消息獲取:int msgget(key_t key,int msgflg)
                    key:IPC鍵
                        key_t ftok(char* path,int id)
                            path:地址
                            id:IP
                        IPC_PRIVATE:通常用於親緣進程
                    msgflg
                        IPC_CREAT【創建】
                        IPC_CREAT|IPC_EXCL
                        權限:可使用八進制數字
                            MSG_R【用戶讀】:0400
                            MSG_W【用戶寫】:0200
                            MSG_R>>3【組讀】:0040
                            MSG_W>>3【組寫】:0020
                            MSG_R>>6【其他讀】:0004
                            MSG_W>>6【其他寫】:0002
                    返回值:非負整數【消息隊列標識】、-1【失敗】
                消息發送:int msgsnd(int msgid,const void* msgptr,size_t msgsz,int msgflg)
                    msgid:消息隊列標識
                    msgptr:消息結構體
                        一個長整型成員變量開始的結構體,消息結構體模板:
                            struct test_message{
                                long mtype;/*must>0*/
                                char mtext;/*data*/
                            };
                    msgsz【消息長度】:不包括長整型變量
                    msgflg【控制函數行爲】:0【忽略】、IPC_NOWAIT【如果消息隊列爲空,則返回一個ENOMSG,並將控制權交回調用函數的進程】、MSG_NOERROR【如果函數取得的消息長度大於msgsz,將只返回msgsz長度的信息,剩下的部分被丟棄了】、MSG_EXCEPT【當msgtype>0時接收類型不等於msgtype的第一條消息】
                    返回值:0【成功】、-1【失敗】
                消息接受:int msgrcv(int msgid,void *msgptr,size_t msgsz,long int msgtype,int msgflg)
                    msggid【消息隊列標識】
                    msgptr【消息結構體】:以一個長整型成員變量開始的結構體
                        struct test_message{
                            long int message_type;
                            /*The data you wish to transfer*/
                        }
                    msgsz【消息長度】:不包括長整型變量
                    msgtype【接收類型】:0【獲取隊列中的第一個消息】、大於0【獲取具有相同消息類型的第一個信息】、小於0【獲取類型等於或小於msgtype的絕對值中最小的一個消息】
                    msgflg【控制函數行爲】:0【忽略】、IPC_NOWAIT【如果消息隊列爲空,則返回一個ENOMSG,並將控制權交回調用函數的進程】、MSG_NOERROR【如果函數取得的消息長度大於msgsz,將只返回msgsz長度的信息,剩下的部分被丟棄了】、MSG_EXCEPT【當msgtype>0時接收類型不等於msgtype的第一條消息】
                    返回值:非負整數【接受到的消息長度】、-1【失敗】
                消息控制:int msggctl(int msgqid,int cmd,struct msqid_ds *buf)
                    msqid【消息隊列標識符】
                    cmd:IPC_STAT【獲取當前消息隊列控制信息】、IPC_SET【設置當前消息隊列控制信息】、IPC_RMID【刪除消息隊列】
                    buf【消息隊列模式結構】:msg_perm.mode【消息隊列讀寫模式】、msg_qbytes【隊列最大大小】、msg_cbytes【當前隊列大小】、msg_qnum【當前隊列消息數】
                    返回值:0【成功】、-1【失敗】
*實例:刪除消息        msgctl(msgqid,IPC_RM,NULL)
            查看:ipcs


                    
           

發佈了68 篇原創文章 · 獲贊 25 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章