进程间通信(四)------消息队列
2017-03-21 15:52
351 查看
消息队列:消息队列提供了一种从⼀个进程向另⼀个进程发送⼀个数据块的⽅方法。每个数据块都被认为是有⼀个类型,接收者进程接收的数据块可以有不同的类型值。可以通过发送消息来避免命名管道的同步和阻塞问题。
特点:基于消息;是用链表实现的;生命周期随内核
每个消息的最⼤大长度是有上限的(MSGMAX)
每个消息队列的总的字节数是有上限的(MSGMNB)
系统上消息队列的总数也有⼀一个上限(MSGMNI)
内核为每个IPC对象维护一个数据结构,消息队列,共享内存和信号量都有这样⼀个共同的数据结构:
comm.h
comm.c
sever.c
client.c
Makefile
运行结果如下所示
特点:基于消息;是用链表实现的;生命周期随内核
每个消息的最⼤大长度是有上限的(MSGMAX)
每个消息队列的总的字节数是有上限的(MSGMNB)
系统上消息队列的总数也有⼀一个上限(MSGMNI)
内核为每个IPC对象维护一个数据结构,消息队列,共享内存和信号量都有这样⼀个共同的数据结构:
comm.h
#ifndef _COMM_H_ #define _COMM_H #define PATHNAME "." #define PROJ_ID 0x666 #define SIZE 128 #define SEVER_TYPE 1 #define CLIENT_TYPE 2 struct msgbuf { long int mtype; /* type of received/sent message*/ char mtext[SIZE]; /* text of the message*/ }; #include<stdio.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> #include<string.h> int createMsg(); int commMsg(int flags); int getMsg(); int sendMsg(int msgid,long type,const char *_info); int recvMsg(int msgid,long type,char out[]); int destroyMsg(int msgid); #endif
comm.c
#include"comm.h" int commMsg(int flags) { key_t key=ftok(PATHNAME,PROJ_ID); if(key<0) { perror("ftok"); return -1; } int msgid=msgget(key,flags); if(msgid<0) { perror("msgget"); return -2; } return msgid; } int createMsg() { return commMsg(IPC_CREAT | IPC_EXCL | 0666); } int getMsg() { return commMsg(IPC_CREAT); } int sendMsg(int msgid, long type,const char *_info) { struct msgbuf msg; msg.mtype=type; strcpy(msg.mtext,_info); msgsnd(msgid,&msg,sizeof(msg.mtext),0); if(msgsnd<0) { perror("msgsnd"); return -1; } return 0; } int recvMsg(int msgid,long type,char out[]) { struct msgbuf msg; if(msgrcv(msgid,&msg,sizeof(msg.mtext),type,0)<0) { perror("msgrcv"); return -1; } strcpy(out,msg.mtext); return 0; } int destroyMsg(int msgid) { if(msgctl(msgid,IPC_RMID,NULL)<0) { perror("msgctl"); return -1; } return 0; }
sever.c
#include"comm.h" int main() { int msgid=createMsg(); printf("msgid=%d\n",msgid); sleep(3); int i=0; long type=SEVER_TYPE; const char *msg="hello world"; char buf[SIZE]; while(1) { //recv->send recvMsg(msgid,CLIENT_TYPE,buf); printf("client# %s\n",buf); printf("Please Enter$ "); fflush(stdout); size_t s=read(0,buf,sizeof(buf)-1); if(s>0) { buf[s-1]='\0'; sendMsg(msgid,SEVER_TYPE,buf); } } sleep(3); destroyMsg(msgid); return 0; }
client.c
#include"comm.h" int main() { int msgid=getMsg(); printf("msgid=%d\n",msgid); int i=0; long type=SEVER_TYPE; const char *msg="hello world"; char buf[SIZE]; while(1) { //send->recv printf("Please Enter$ "); fflush(stdout); size_t s=read(0,buf,sizeof(buf)-1); if(s>0) { buf[s-1]='\0'; sendMsg(msgid,CLIENT_TYPE,buf); } recvMsg(msgid,SEVER_TYPE,buf); printf("sever# %s\n",buf); } //destroyMsg(msgid); return 0; }
Makefile
client_=client sever_=sever cc=gcc cliSrc=client.c comm.c seSrc=sever.c comm.c .PHONY:all all:$(client_) $(sever_) $(client_):$(cliSrc) $(cc) -o $@ $^ $(sever_):$(seSrc) $(cc) -o $@ $^ .PHONY:clean clean: rm -f $(client_) $(sever_)
运行结果如下所示
相关文章推荐
- 8.进程间通信---消息队列
- Linux环境进程间通信(三):消息队列
- Linux 进程间通信(posix消息队列 简单)实例
- Linux进程间通信(简单的消息队列通信)
- 多进程编程之进程间通信-管道和消息队列
- 进程间通信系列 之 消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列 分类: Linux --- 应用程序设计 2014-11-11 13:16 71人阅读 评论(0) 收藏
- 进程间通信之消息队列和信号量
- boost进程间通信经常使用开发一篇全(消息队列,共享内存,信号)
- Linux进程间通信——使用消息队列
- Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存
- Linux的进程编程-之二-进程间通信(消息队列)
- 进程间通信之消息队列
- 进程间通信(IPC)之消息队列
- Linux下进程间通信之消息队列
- Linux系统编程——进程间通信:消息队列
- 8、linux进程间通信之消息队列
- 4、进程间通信-消息队列IPC
- Vxworks 进程间通信1--消息队列
- 进程间通信——消息队列