1.消息队列(queue)
版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.cnblogs.com/Dana-gx/p/9724545.html
一、基本概念
区别:
1> 避免命名管道的同步和阻塞问题
共享内存每列详解:
第一列就是共享内存的key; 第二列是共享内存的编号shmid;
五、system v下的消息队列接口函数:创建、发送、接受和删除
int msgget (key_t key, int msgflg);
msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz,long msg_typ, int msgflg);
msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
int msgctl (int msqid, int cmd, struct msqid_ds *buf);
5.1 msgget函数 用来创建和访问一个消息队列 函数原型如下:
int msgget (key_t key, int msgflg);
key: 某个特定消息队列的键值int msgsnd (int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
msgid: 由msgget函数返回的消息队列标识码
struct my_message{
long message_type; /* The data you wish to transfer*/
char text[size]; /*the data*/
};
msg_sz:是msg_ptr指向的消息长度,这个长度不能保存消息类型的那个“long int”长整型计算在内5.3 msgrcv函数 函数原型如下:
int msgrcv(int msgid, void *msg_ptr, size_t msgsz, long int msgtype,int msgflg);5.4 msgctl函数 控制消息队列,与共享内存shmctl相似 函数原型如下:
int msgctl(int msqid, int command, strcut msqid_ds *buf);
struct msgid_ds {
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};
历程代码: 分为四个部分,创建消息队列、不同进程接收发和删除消息队列
1.创建key为0x1000的消息队列: msgget.c文件
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<sys/ipc.h> 4 #include<sys/msg.h> 5 #include<stdlib.h> 6 7 8 int main(int argc, char *argv[]) 9 { 10 int ret = msgget((key_t)0x1000, IPC_CREAT | IPC_EXCL | 0666); 11 if(ret == -1) 12 { 13 perror("msgget"); 14 exit(EXIT_FAILURE); 15 } 16 printf("Message id = %d \n",ret); 17 return 0; 18 }
2.往0x1000消息队列写数据: msgsnd.c文件
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<sys/ipc.h> 4 #include<sys/msg.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<getopt.h> 8 9 typedef struct msgbuf 10 { 11 long mtype; 12 char mtext[1024]; 13 }msgbuf_t; 14 int main(int argc, char* argv[]) 15 { 16 int msgid = msgget((key_t)0x1000, 0); 17 if(msgid == -1) 18 { 19 perror("msgget"); 20 exit(EXIT_FAILURE); 21 } 22 char c; 23 msgbuf_t msg= {-1,0}; 24 while((c = getopt(argc, argv, "t:m:")) != -1) 25 { 26 switch(c) 27 { 28 case 't': 29 msg.mtype = atoi(optarg); 30 break; 31 case 'm': 32 strcpy(msg.mtext, optarg); 33 break; 34 default: 35 fprintf(stderr, "error option! \n"); 36 printf("%s -t msgttpe -m message \n",argv[0]); 37 break; 38 } 39 } 40 if(msg.mtype > 0 && msg.mtext[0] != 0) 41 { 42 if(msgsnd(msgid, &msg, strlen(msg.mtext), 0) == -1) 43 { 44 perror("msgsnd"); 45 exit(EXIT_FAILURE); 46 } 47 } 48 return 0; 49 }
3.从0x1000消息队列读数据: msgrcv.c文件
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<sys/ipc.h> 4 #include<sys/msg.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<getopt.h> 8 9 typedef struct msgbuf 10 { 11 long mtype; 12 char mtext[1024]; 13 }msgbuf_t; 14 15 int main(int argc, char* argv[]) 16 { 17 int msgid = msgget((key_t)0x1000, 0); 18 if(msgid == -1) 19 { 20 perror("msgget"); 21 exit(EXIT_FAILURE); 22 } 23 24 char c; 25 msgbuf_t msg= {-1,0}; 26 while((c = getopt(argc, argv, "t:m:")) != -1) 27 { 28 switch(c) 29 { 30 case 't': 31 msg.mtype = atoi(optarg); 32 break; 33 default: 34 fprintf(stderr, "error option! \n"); 35 printf("%s -t msgttpe -m message \n",argv[0]); 36 break; 37 } 38 } 39 if(msg.mtype > 0 ) 40 { 41 if(msgrcv(msgid, &msg, sizeof(msg)-5, msg.mtype, IPC_NOWAIT) == -1) 42 { 43 perror("msgsnd"); 44 exit(EXIT_FAILURE); 45 } 46 printf("msgtype = %ld, msg = %s \n",msg.mtype,msg.mtext); 47 } 48 return 0; 49 }
4.删除消息队列: msgctl.c文件
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<sys/ipc.h> 4 #include<sys/msg.h> 5 #include<stdlib.h> 6 #include<string.h> 7 8 int main(int argc, char* argv[]) 9 { 10 int msgid = msgget((key_t)0x1000, 0); 11 if(msgid == -1) 12 { 13 perror("msgget"); 14 exit(EXIT_FAILURE); 15 } 16 if(msgctl(msgid, IPC_RMID, NULL) == -1) 17 { 18 perror("msgctl"); 19 exit(EXIT_FAILURE); 20 } 21 return 0; 22 }
Linux下运行过程如下: