Linux --进程间通信--消息队列
程序员文章站
2022-05-23 17:24:13
...
一、消息队列的定义
消息队列能够弥补管道的不足,实现双向交互数据,是一个进程向另一进程发送进程块的方法。与管道不同的是,管道是基于字节流的,消息队列是基于消息的,且消息队列的读取不一定是先进先出。
二、消息队列的创建
通过函数int messget(key_t key,int msgflg);创建
key:端口号,可以有 ftok生成。
msgflg:
IPC_CRTAT 若果 IPC不存在,则创建一个IPC资源,
IPC_EXCL:一般和 IPC_CREAT一起使用可以保证所得的对象是新建的,而不是打开已有的。
三、向消息队列读数据
msgrcv从队列中取的消息
ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);
msgsnd将消息放进队列中
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
四、设置消息队列属性
int msgctl(int msgqid,int cmd,struct msqid_ds *buf);
*** 可以用man 函数名 查看函数***
程序代码:
coom.h
消息队列能够弥补管道的不足,实现双向交互数据,是一个进程向另一进程发送进程块的方法。与管道不同的是,管道是基于字节流的,消息队列是基于消息的,且消息队列的读取不一定是先进先出。
二、消息队列的创建
通过函数int messget(key_t key,int msgflg);创建
key:端口号,可以有 ftok生成。
msgflg:
IPC_CRTAT 若果 IPC不存在,则创建一个IPC资源,
IPC_EXCL:一般和 IPC_CREAT一起使用可以保证所得的对象是新建的,而不是打开已有的。
三、向消息队列读数据
msgrcv从队列中取的消息
ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);
msgsnd将消息放进队列中
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
四、设置消息队列属性
int msgctl(int msgqid,int cmd,struct msqid_ds *buf);
*** 可以用man 函数名 查看函数***
程序代码:
coom.h
1 #pragma once 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<sys/types.h> 6 #include<sys/ipc.h> 7 #include<sys/msg.h> 8 #define _PATH_ "." 9 #define _PROCID_ 0x776 10 #define _SIZE 1024 11 #define SERVE_MSGTYPE 1 12 #define CLIECT_MSGTYPE 2 13 typedef struct message 14 { 15 long mtype; 16 char mtext[_SIZE]; 17 }message; 18 int create_msg(int msg_num); 19 int drstroy_msg(int msg_id); 20 int set_msg(); 21 int get_msg(); 22 int msg_send(int msg_id,const char* msg,long type); 23 int msg_rec(int msg_id ,char buf[],long type);
comm .c
1 #include"comm.h" 2 int create_msg(int msg_num) 3 { 4 key_t _key=ftok(_PATH_,_PROCID_); 5 if(_key < 0) 6 { 7 perror("ftok"); 8 return -1; 9 } 10 int ret= msgget(_key,msg_num); 11 if(ret < 0) 12 { 13 perror("msgget"); 14 return -1; 15 } 16 return ret; 17 } 18 int drstroy_msg(int msg_id) 19 { 20 if(msgctl(msg_id,IPC_RMID,NULL) < 0) 21 { 22 perror("msgctl"); 23 return -1; 24 }else{ 25 printf("remove message_queue\n"); 26 return 0; 27 } 28 } 29 int set_msg() 30 { 31 umask(0); 32 return create_msg(IPC_CREAT |IPC_EXCL |0666); 33 } 34 int get_msg() 35 { 36 return create_msg(IPC_CREAT); 37 } 38 int msg_send(int msg_id,const char* msg,long type) 39 { 40 struct message _msg; 41 _msg.mtype=type; 42 strcpy(_msg.mtext,msg); 43 if(msgsnd(msg_id,&_msg,strlen(_msg.mtext),0)< 0) 44 { 45 perror("msg_send error"); 46 return -1; 47 } 48 return 0; 49 } 50 int msg_rec(int msg_id,char buf[],long type) 51 { 52 struct message _msg; 53 memset(_msg.mtext,'\0',_SIZE); 54 if(msgrcv(msg_id,&_msg,_SIZE,type,0)< 0) 55 { 56 perror("msg_receve error"); 57 return -1; 58 } 59 strcpy(buf,_msg.mtext); 60 return 0; 61 } 62
client.c
1 #include"comm.h" 2 int main() 3 { 4 int msg_id=get_msg(); 5 if(msg_id<0) 6 { 7 perror("error"); 8 exit(1); 9 } 10 char buf[_SIZE]; 11 while(1) 12 { 13 fflush(stdout); 14 printf("please client input: "); 15 memset(buf,'\0',_SIZE); 16 fgets (buf,sizeof(buf),stdin); 17 if(msg_send(msg_id,buf,CLIECT_MSGTYPE)< 0) 18 { 19 perror("send fail"); 20 exit(1); 21 } 22 23 if(msg_rec(msg_id,buf,SERVE_MSGTYPE)<0) 24 { 25 perror("recve fail"); 26 exit(1); 27 } 28 printf("serve:%s" ,buf); 29 } 30 return 0; 31 }
server.c
1 #include "comm.h" 2 int main() 3 { 4 int msg_id=set_msg(); 5 if(msg_id<0) 6 { 7 perror("mig_id"); 8 exit(1); 9 } 10 printf("%d\n",msg_id); 11 char buf[_SIZE]; 12 while(1) 13 { 14 if(msg_rec(msg_id,buf,CLIECT_MSGTYPE)< 0) 15 { 16 perror("recve fail"); 17 exit(1); 18 } 19 else 20 { 21 printf("client :%s",buf); 22 } 23 printf("server please input: "); 24 fflush(stdout); 25 memset(buf,'\0',_SIZE); 26 fgets(buf,_SIZE,stdin); 27 if(msg_send(msg_id,buf,SERVE_MSGTYPE)<0) 28 { 29 perror("send fail"); 30 exit(1); 31 } 32 } 33 drstroy_msg(msg_id); 34 return 0; 35 }
运行结果:
以上就是Linux --进程间通信--消息队列的内容,更多相关内容请关注PHP中文网(www.php.cn)!