Linux系統程式設計 POSIX訊息佇列

2021-09-11 04:20:58 字數 2970 閱讀 1121

posix訊息佇列就是程序之間通訊的方式之一,其特點是以訊息的形式交換資料(資料的交換單位是整個訊息),posix訊息佇列和system v訊息佇列相比,有以下優點:

訊息通知特性允許乙個程序能在一條訊息進入之前為空的訊息佇列時候,非同步的通過訊號或者執行緒的例項化接收通知

linux下可以通過poll()、select()、epoll監控posix訊息佇列

在fork()中子程序會接受其父程序的訊息佇列描述符的副本,並且這些描述符會引用相同的開啟著的訊息佇列。

#include mqd_t mq_open(const char *name,int oflag,/* mode_t mode , struct mq_attr *attr */);

//mq_open()函式創造乙個新的訊息佇列或者開啟乙個已有的訊息佇列,返回訊息佇列描述符

//name引數標識訊息佇列

//oflag引數有以下取值o_create,o_excl,o_rdonly,o_rdwr,o_wronly(三選一),o_nonblock

//如果取值包含了o_create,則說明如果name訊息佇列不存在則會新建乙個,同時還需指定mode和attr

//mode是位掩碼,和檔案上的掩碼值是一樣的,將讀寫許可權付給相應的使用者

//attr是指定新訊息佇列的特性,預設則為null

int mq_close(mqd_t mqdes);

//關閉訊息佇列描述符,當程序終止或者呼叫exec()時候,自動關閉訊息佇列描述符

int mq_unlink(const char *name);

//函式刪除通過name標示的訊息佇列,並將訊息佇列標記為在所有程序使用完該訊息佇列之後銷毀該佇列

訊息佇列描述符和訊息佇列的關係如同檔案描述符和檔案的關係,如下圖:

//獲取訊息佇列的特性

int mq_setattr(mqd_t mqdes,const struct mq_attr *newattr,struct mq_attr *oldattr);

//修改訊息佇列特性

//如果oldattr不為null,那麼則返回乙個包含之前訊息佇列標記和訊息佇列特性的mq_attr

int mq_send(mqd_t mqdes,const char *msg_ptr,size_t msg_len,unsigned int msg_prio);

//函式將msg_ptr指向的緩衝區中的訊息新增到訊息描述符mqdes所引用的訊息佇列中

//msg_len表示訊息緩衝區中訊息的長度,其值要小於或等於佇列的mq_msgsize屬性

//msg_prio表示優先順序,數字越大優先順序越高(若優先順序相同則先入先出)

ssize_t mq_receive(mqd_t mqdes,char *msg_ptr, size_t msg_len,unsigned int *msg_prio);

//接收訊息的時候,msg_len表示訊息緩衝區中訊息的長度,其值要大於或等於佇列的mq_msgsize屬性

//優先順序可以設為null

如果訊息佇列已經滿了(即達到mq_maxmsg限制),那麼後續呼叫mq_send()函式會阻塞知道佇列中存在可用空間或者如果標記有o_nonblock則立刻返回失敗。同理,如果訊息佇列當前在空,那麼呼叫mq_receive()也會阻塞。

還有兩個mq_timedsend()和mq_timedreceive()幾乎作用於前兩個一樣,唯一差別在於可設定乙個訊息超時設定。

下面的例子在父子程序之間利用訊息佇列通訊。

#include #include #include #include #include #include #include #include int main(int argc,char *ar**)

int pid;

struct mq_attr attr;

if(mq_getattr(mq,&attr)==-1)

printf("maxmsg is %ld\n",attr.mq_maxmsg);

printf("mq_msgsize is %ld\n",attr.mq_msgsize);

printf("mq_curmsgs is %ld\n",attr.mq_curmsgs);

pid=fork();

if(pid<0)

else if(pid==0)

mq_send(mq,buf_send,sizeof(buf_send)+1,3);

mq_send(mq,buf_send,sizeof(buf_send)+1,2);

_exit(0);

}else

printf("%s\n",buff);

}mq_close(mq);

mq_unlink("/new_mq");

}return 0;

}

posix訊息佇列可以讓程序接受之前為空的佇列上有可用訊息的非同步通知。一種方法通過訊號接收通知,另一種通過執行緒接收通知。

int mq_notify(mqd_t mqdes,const struct sigevent *notification);

//mq_notify函式註冊呼叫程序在一條訊息進入描述符所引用的空佇列時接收通知

使用的時候,需要注意以下幾點:

任何乙個時刻只有乙個程序能夠向乙個指定訊息佇列註冊接收通知。

只有當一條新訊息進入之前為空的佇列時候註冊程序才會收到通知。

當向乙個註冊程序傳送乙個通知之後就會刪除註冊資訊,之後任何程序就可以向該佇列註冊接收通知了。

參考 《tlpi》

Linux 系統程式設計

1 i o操作 2 檔案和目錄管理 3 記憶體管理 1 建立匿名記憶體對映 2 對映 dev zero檔案 類unix 作業系統中,dev zero是乙個特殊的檔案,當你讀它的時候,它會提供無限的空字元 null,ascii nul,0x00 其中的乙個典型用法是用它提供的字元流來覆蓋資訊,另乙個常...

Linux系統程式設計

1.linux程序 守護程序 脫離終端的後台程序 2.linux程序 殭屍程序 3.linux 下程序通訊 其中setsockopt server sockfd,sol socket,so reuseaddr,on,sizeof on 因為每乙個連線都由本地位址和遠端位址的組合唯一確定,所以只要遠端...

Linux系統程式設計 Linux系統呼叫

linux 系統呼叫 庫函式 目錄 系統呼叫概述 系統呼叫的實現 系統呼叫和庫函式的區別 系統呼叫,顧名思義,說的是作業系統提供給使用者程式呼叫的一組 特殊 介面。使用者程式可以通過這組 特殊 介面來獲得作業系統核心提供的服務,比如使用者可以通過檔案系統相關的呼叫請求系統開啟檔案 關閉檔案或讀寫檔案...