日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux IPC实践(5) --System V消息队列(2)

發(fā)布時間:2025/3/17 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux IPC实践(5) --System V消息队列(2) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

消息發(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的第一條消息

/** 示例2: 消息接收(配合示例1中程序使用) 說明: -t [number], 指定接收消息的類型, 類型為number的值 -n ,指定以IPC_NOWAIT模式接收消息 **/ int main(int argc, char *argv[]) {/** 解析參數(shù) **/int type = 0;int flag = 0;int opt;while ((opt = getopt(argc, argv, "nt:")) != -1){switch (opt){case 'n': // 指定IPC_NOWAIT選項flag |= IPC_NOWAIT;break;case 't': // 指定接收的類型, 如果為0的話,說明是按照順序接收type = atoi(optarg);break;default:exit(EXIT_FAILURE);}}int msgid = msgget(0x255, 0);if (msgid == -1)err_exit("msgget error");const int MSGMAX = 8192; //指定一條消息的最大長度struct msgbuf *buf;buf = (struct msgbuf *)malloc(MSGMAX + sizeof(buf->mtype));ssize_t nrcv;if ((nrcv = msgrcv(msgid, buf, MSGMAX, type, flag)) == -1)err_exit("msgrcv error");cout << "recv " << nrcv << " bytes, type = " << buf->mtype << endl; }
/** 綜合示例: 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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。