【Linux】IPC通信之消息队列
来源:互联网 发布:facebook程序员面试题 编辑:程序博客网 时间:2024/05/21 09:19
消息队列概念
消息队列提供了一个进程将一个数据块发送到另一个进程的方法。
相比于管道的同步与阻塞,消息队列很好的解决了这个问题
管道通信是基于字节流的,然而消息队列发送的是一个数据结构,即IPC对象
消息队列的总字节数是有上限的,消息队列的总数也是有一定上限的
IPC对象的内容(消息队列,信号量和共享内存共同的IPC对象)
消息队列的结构
与消息队列有关的函数
头文件
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
消息队列的创建
函数
int msgget(int key, int flags)
key是 int ftok(const char* pathname, int PROJ_ID)的返回值,其中pathname是路径名,PROJ_ID是工程号
flags有两个参数,分别是IPC_CREAT和IPC_EXCL
IPC_CREAT 单独使用时,创建一个IPC资源,如果资源已经存在,则获得当前存在的资源
IPC_EXCL 只有在共享内存不存在时进行创建,如果存在则会报错
当IPC_CREAT和IPC_EXCL共同使用时,返回一个新建的IPC标识符,如果IPC资源已经存在则返回-1,从而保证对象是新建产生的
消息队列的销毁
函数
int msgctl(int msg_id, int cmd, struct msqid_ds* buf)
msgctl系统调用对msgqid标识的消息队列执行cmd操作
系统定义的三种cmd操作:IPC_STAT,IPC_SET,IPC_RMID
IPC_STAT:获取msqid_ds数据结构,并保存到buf所指向的地址空间
IPC_SET:设置消息队列的属性,并存储到buf中
IPC_RMID:从系统中删除msgqid标识的消息队列
消息队列的发送
函数
int msgsnd(int msqid,const void* msgp,size_t msgsz,int msgflg)
msqid:消息队列的表识码
msgp:指向消息缓冲区的指针,来暂时存储发送和接受的消息,是一个用户自定义的数据结构
struct msgstru
{
long mType;
char mText[大小可变];
};
msgsz:消息队列的大小
msgflg:当msgflg为0时,msgsnd()或msgrcv()呈现满或者空的情形时,采取阻塞等待处理的模式
消息队列的接受
函数
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
msgtyp:表示从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都 会被读取。
Linux下查看系统中的IPC信息
ipcs -q
Linux下删除系统中的IPC信息
ipcrm -q
代码实现消息队列
comm.h
#include"comm.h"int main(){int msqid = CreatMsgQueue();if(msqid < 0){perror("CreatMsgQueue");return -1;}char buf[1024];while(1){buf[0] = 0;if(RcvMsg(msqid,CLIENT_TYPE,buf) == -1){perror("RevMsg");return -2;}printf("Client# %s",buf);printf("Server Enter#");fflush(stdout);ssize_t s = read (0,buf,sizeof(buf)-1);if(s < 0){perror("read");return -3;}buf[s] = 0;if(SndMsg(msqid,SERVER_TYPE,buf) == -1){perror("SndMsg");return -4;}}DestoryMsgQueue(msqid);return 0;}
comm.c
#include"comm.h"int main(){int msqid = CreatMsgQueue();if(msqid < 0){perror("CreatMsgQueue");return -1;}char buf[1024];while(1){buf[0] = 0;if(RcvMsg(msqid,CLIENT_TYPE,buf) == -1){perror("RevMsg");return -2;}printf("Client# %s",buf);printf("Server Enter#");fflush(stdout);ssize_t s = read (0,buf,sizeof(buf)-1);if(s < 0){perror("read");return -3;}buf[s] = 0;if(SndMsg(msqid,SERVER_TYPE,buf) == -1){perror("SndMsg");return -4;}}DestoryMsgQueue(msqid);return 0;}
client.c
#include"comm.h"int main(){int msqid = GetMsgQueue();if(msqid < 0){perror("GetMsgQueue");return -1;}char buf[1024];while(1){buf[0] = 0;printf("Client Enter# ");fflush(stdout);ssize_t s = read(0,buf,sizeof(buf)-1);if(s < 0){perror("read");return -2;}buf[s] = 0;if(SndMsg(msqid,CLIENT_TYPE,buf)<0){perror("SndMsg");return -3;}if(RcvMsg(msqid,SERVER_TYPE,buf)<0){perror("RcvMsg");return -4;}printf("Server echo# %s",buf);}return 0;}
server.c
#include"comm.h"int main(){int msqid = CreatMsgQueue();if(msqid < 0){perror("CreatMsgQueue");return -1;}char buf[1024];while(1){buf[0] = 0;if(RcvMsg(msqid,CLIENT_TYPE,buf) == -1){perror("RevMsg");return -2;}printf("Client# %s",buf);printf("Server Enter#");fflush(stdout);ssize_t s = read (0,buf,sizeof(buf)-1);if(s < 0){perror("read");return -3;}buf[s] = 0;if(SndMsg(msqid,SERVER_TYPE,buf) == -1){perror("SndMsg");return -4;}}DestoryMsgQueue(msqid);return 0;}
makefile
#include"comm.h"int main(){int msqid = CreatMsgQueue();if(msqid < 0){perror("CreatMsgQueue");return -1;}char buf[1024];while(1){buf[0] = 0;if(RcvMsg(msqid,CLIENT_TYPE,buf) == -1){perror("RevMsg");return -2;}printf("Client# %s",buf);printf("Server Enter#");fflush(stdout);ssize_t s = read (0,buf,sizeof(buf)-1);if(s < 0){perror("read");return -3;}buf[s] = 0;if(SndMsg(msqid,SERVER_TYPE,buf) == -1){perror("SndMsg");return -4;}}DestoryMsgQueue(msqid);return 0;}
运行结果
- 【Linux】IPC通信之消息队列
- Linux — IPC进程通信之消息队列详解
- Linux IPC 之消息队列
- linux IPC之消息队列
- linux IPC之消息队列
- Linux IPC 之消息队列
- Linux 进程间通信 (IPC) // 消息队列
- Linux进程通信IPC--消息队列MessageQueue
- 进程通信 IPC 之消息队列
- 进程间通信(IPC)之消息队列
- Linux XSI IPC 之消息队列
- linux IPC之POSIX消息队列
- linux下IPC之消息队列
- linux IPC-消息队列
- linux IPC-消息队列
- Linux IPC- 消息队列
- linux IPC--消息队列
- linux IPC---消息队列
- JS内外部函数调用关系
- 三次样条+线性插值
- 类对象
- Spring面向切面编程AOP
- 14面向对象模型初探
- 【Linux】IPC通信之消息队列
- java获取键盘输入
- jQuery 二级联动(客户端、栏目)
- 2.安装--以及简单使用(二)
- 列车调度(Train)
- 记录 idea java类实现序列化后生成序列化id
- 欢迎使用CSDN-markdown编辑器
- C学习笔记
- while read line只读一行或者最后一行读不到