Linux IPC实践(5) --System V消息队列(2)
消息發(fā)送/接收API
msgsnd函數(shù)
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);參數(shù)
? ?msgid:?由msgget函數(shù)返回的消息隊列標識碼,?也可以是通過ipcs命令查詢出來的一個已經存在的消息隊列的ID號
? ?msgp:是一個指針,指針指向準備發(fā)送的消息,
? ?msgsz:是msgp指向的消息長度,?注意:這個長度不含保存消息類型的那個long?int長整型
? ?msgflg:控制著當前消息隊列滿或到達系統(tǒng)上限時將要發(fā)生的事情,如果msgflg?=?IPC_NOWAIT表示隊列滿不等待,返回EAGAIN錯誤。
消息結構在兩方面受到制約:?(1)它必須小于系統(tǒng)規(guī)定的上限值(MSGMAX);?(2)它必須以一個long?int長整數(shù)開始,接收者函數(shù)將利用這個長整數(shù)確定消息的類型;
//消息結構參考形式如下: struct msgbuf {long mtype; /* message type, must be > 0 */char mtext[1]; /* message data, 可以設定為更多的字節(jié)數(shù) */ }; /**示例1: 測試1: 發(fā)送消息的最大長度為8192字節(jié), 一旦超過這個值, 則msgsnd出錯, 提示 Invalid argument錯誤; 測試2: 消息隊列所能夠接收的最大字節(jié)數(shù)16384字節(jié), 一旦超過這個長度, 如果msgflg為0(阻塞模式), 則進程會一直阻塞下去, 直到有進程來將消息取走; 而如果msgflg為IPC_NOWAIT模式, 則一個字節(jié)也不會寫入消息隊列, 直接出錯返回; **/ int main(int argc, char *argv[]) {if (argc != 3)err_quit("Usage: ./main <type> <length>");int type = atoi(argv[1]);int len = atoi(argv[2]);int msgid = msgget(0x255, 0666|IPC_CREAT);if (msgid == -1)err_exit("msgget error");struct msgbuf *buf;buf = (struct msgbuf *)malloc(len + sizeof(msgbuf::mtype));buf->mtype = type;if (msgsnd(msgid, buf, len, IPC_NOWAIT) == -1)err_exit("msgsnd error"); }msgrcv函數(shù)
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);參數(shù)
? ?msgid:?由msgget函數(shù)返回的消息隊列標識碼
? ?msgp:是一個指針,指針指向準備接收的消息;
? ?msgsz:是msgp指向的消息長度,這個長度不含保存消息類型的那個long?int長整型
? ?msgtype:它可以實現(xiàn)接收優(yōu)先級的簡單形式(見下圖)
? ?msgflg:控制著隊列中沒有相應類型的消息可供接收時將要發(fā)生的事(見下圖)
返回值:
? ?成功->返回實際放到接收緩沖區(qū)里去的字節(jié)數(shù)(注意:?此處并不包含msgbuf中的mtype的長度[man-page:?msgrcv()?returns?the?number?of?bytes?actually?copied?into?the?mtext?array.]);
? ?失敗->返回-1;
?
msgtyp參數(shù) | |
msgtyp=0 | 返回隊列第一條信息 |
msgtyp>0 | 返回隊列第一條類型等于msgtype的消息 |
msgtyp<0 | 返回隊列第一條類型小于等于(<=)msgtype絕對值的消息,并且是滿足條件的消息類型最小的消息(按照類型進行排序的順序進行接收消息) |
?
msgflg參數(shù) | |
msgflg=IPC_NOWAIT | 隊列沒有可讀消息不等待,返回ENOMSG錯誤。 |
msgflg=MSG_NOERROR | 消息大小超過msgsz(msgrcv?函數(shù)的第三個參數(shù))時被截斷,?并且不會報錯 |
msgtyp>0且msgflg=MSG_EXCEPT | 接收類型不等于msgtype的第一條消息 |
/** 綜合示例: msgsnd/msgrcv, 消息發(fā)送/接收實踐 **/ //1. 消息發(fā)送 int main() {int msgid = msgget(0x1234,0666|IPC_CREAT);if (msgid == -1)err_exit("msgget error");struct msgBuf myBuffer;for (int i = 0; i < 128; ++i){myBuffer.mtype = i+1;sprintf(myBuffer.mtext,"Hello, My number is %d",i+1);if (msgsnd(msgid,&myBuffer,strlen(myBuffer.mtext),IPC_NOWAIT) == -1)err_exit("msgsnd error");} } //2. 消息接收:從隊首不斷的取數(shù)據 int main(int argc, char *argv[]) {int msgid = msgget(0x1234, 0);if (msgid == -1)err_exit("msgget error");struct msgBuf buf;ssize_t nrcv;while ((nrcv = msgrcv(msgid, &buf, sizeof(buf.mtext), 0, IPC_NOWAIT)) > 0){cout << "recv " << nrcv << " bytes, type: " << buf.mtype<< ", message: " << buf.mtext << endl;} }
[附]-getopt函數(shù)的用法
#include <unistd.h> int getopt(int argc, char * const argv[],const char *optstring);extern char *optarg; extern int optind, opterr, optopt; //示例: 解析 ./main -n -t 3 中的參數(shù)選項 int main(int argc, char *argv[]) {while (true){int opt = getopt(argc, argv, "nt:");if (opt == '?')exit(EXIT_FAILURE);else if (opt == -1)break;switch (opt){case 'n':cout << "-n" << endl;break;case 't':int n = atoi(optarg);cout << "-t " << n << endl;break;}} }新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產品紅包拿不停!
總結
以上是生活随笔為你收集整理的Linux IPC实践(5) --System V消息队列(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2012年6月7日
- 下一篇: linux 其他常用命令