linux 消息队列_Linux进程间通信第六讲 标准IPC之消息队列
來源CSDN:
CSDN-專業(yè)IT技術(shù)社區(qū)-登錄?blog.csdn.net一、概念和原理
消息隊列是另一種標準IPC,當然也大概遵循大部分標準
消息隊列,它是存放消息(數(shù)據(jù))的隊列,而隊列是先進先出的線性數(shù)據(jù)結(jié)構(gòu)
換句話說,我們就是利用這個數(shù)據(jù)結(jié)構(gòu) 進行進程間的通信
消息隊列允許多個進程同時讀寫消息.由于消息可以定義很多類型,取出時可以指定哪個消息類型取出,所以消息隊列解決了共享內(nèi)存多個進程同時讀寫時數(shù)據(jù)混亂的問題,只要把消息標定不同的類型即可
二、使用
1)通過ftok獲取key
2)通過key 創(chuàng)建/獲取 消息隊列 ------- msgget
參數(shù):
key - 上一步獲取的key
msgflg - 創(chuàng)建標志和權(quán)限
IPC_CREAT|0666
成功返回消息隊列ID,失敗返回-1
3)把消息 存入隊列 / 從隊列中取出 ----------- msgsnd/msgrcv
參數(shù):msqid - 消息隊列IDmsgq - 消息首地址msgsz - 消息長度(消息數(shù)據(jù)的長度)msgtyp - 用來指定接收什么類型的消息(僅僅接收消息時才有)0:接收任意類型消息(第一個,先進先出)>0:接收類型為msgtyp的特定消息<0:接收類型 小于等于 msgtyp絕對值的小,類型從小到大接收msgflg - 接收/發(fā)送 標識0表示阻塞方式操作,接收消息沒有消息可接收/發(fā)送消息消息隊列滿了 就會等待直到成功IPC_NOWAIT表示非阻塞方式操作,接收消息沒有消息可接收/發(fā)送消息消息隊列滿了 直接返回錯誤msgsnd成功返回0,msgrcv成功返回收到消息的消息數(shù)據(jù)長度,失敗都返回-1
另外,消息類型在系統(tǒng)中是未定義的,所以程序員需要在代碼中自己定義消息的類型,但是必須按照以下形式:
struct msgbuf {long mtype; /* 消息類型, 必須大于0 */char mtext[1]; /* 消息數(shù)據(jù), 即存放的數(shù)據(jù) */};4)不再使用可以刪除消息隊列 ------- msgctl
參數(shù):msqid - 消息隊列IDcmd - 命令IPC_RMID:刪除IPC_SET: 修改IPC_STAT: 獲取buf - 設置/獲取 時 傳入/傳出 消息隊列的信息, 下面是它的數(shù)據(jù)類型 ,其中可以修改的是uid、gid和modemsgctl函數(shù)成功返回0,失敗返回-1
struct msqid_ds {struct ipc_perm msg_perm; /* Ownership and permissions */time_t msg_stime; /* 最后發(fā)送消息時間 */time_t msg_rtime; /* 最后接收消息時間 */time_t msg_ctime; /* 最后修改時間 */unsigned long __msg_cbytes; /* 當前使用消息隊列空間大小 (nonstandard) */msgqnum_t msg_qnum; /* 當前消息個數(shù) */msglen_t msg_qbytes; /* 消息隊列最大長度 */pid_t msg_lspid; /* 最后發(fā)送消息的PID */pid_t msg_lrpid; /* 最后接收消息的PID */};struct ipc_perm {key_t __key; /* Key supplied to msgget(2) */uid_t uid; /* Effective UID of owner */gid_t gid; /* Effective GID of owner */uid_t cuid; /* Effective UID of creator */gid_t cgid; /* Effective GID of creator */unsigned short mode; /* Permissions */unsigned short __seq; /* Sequence number */};消息隊列發(fā)送端代碼如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/msg.h>struct MSG{long mtype;char mtext[100]; };int main() {//1.獲取keykey_t key = ftok(".",'x');if(key==-1){perror("ftok");exit(-1);}//2.創(chuàng)建消息隊列int msqid = msgget(key,IPC_CREAT|0666);if(msqid==-1){perror("shmget");exit(-1);}//3.發(fā)送消息struct MSG msg1;msg1.mtype = 1;//類型1strcpy(msg1.mtext,"liubei");int res = msgsnd(msqid,&msg1,sizeof(msg1.mtext),0);if(res==-1){perror("msgsnd");exit(-1);}msg1.mtype = 2;//類型2strcpy(msg1.mtext,"guanyu");res = msgsnd(msqid,&msg1,sizeof(msg1.mtext),0);if(res==-1){perror("msgsnd");exit(-1);}printf("消息發(fā)送成功!n");return 0; }消息隊列接收端代碼如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/msg.h> #include <errno.h>extern int errno;struct MSG{long mtype;char mtext[100]; };int main() {//1.獲取keykey_t key = ftok(".",'x');if(key==-1){perror("ftok");exit(-1);}//2.獲取消息隊列int msqid = msgget(key,0);if(msqid==-1){perror("shmget");exit(-1);}//3.接收消息struct MSG msg1;while(1){//類型-2,方式非阻塞int res = msgrcv(msqid,&msg1,sizeof(msg1.mtext),/*-2*/0,IPC_NOWAIT);//接收完成刪除消息隊列if(res==-1&&errno==ENOMSG){break;}else if(res==-1&&errno!=ENOMSG){perror("msgrcv");exit(-1);}else{printf("消息類型 = %ld,消息內(nèi)容 = %sn",msg1.mtype,msg1.mtext);}}msgctl(msqid,IPC_RMID,0);printf("消息隊列刪除成功!n");return 0; }輸出如下:
liaowenbindeMacBook-Pro:3 liaowenbin$ ./4msg 消息發(fā)送成功! liaowenbindeMacBook-Pro:3 liaowenbin$ gcc 5msg.c -o 5msg liaowenbindeMacBook-Pro:3 liaowenbin$ ./5msg 消息類型 = 1,消息內(nèi)容 = liubei 消息類型 = 2,消息內(nèi)容 = guanyu 消息隊列刪除成功!總結(jié)
以上是生活随笔為你收集整理的linux 消息队列_Linux进程间通信第六讲 标准IPC之消息队列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020年做什么能够发财?
- 下一篇: linux 信号_Linux中的信号处理