进程通信2——消息队列
来源:互联网 发布:java使用hbase数据库 编辑:程序博客网 时间:2024/06/07 14:08
消息队列是由链表实现的,它是基于system V标准。
特点:
- 双向通信;
- 基于消息(数据块);
- 不遵循“先入先出”的原则;
- 生命周期随内核;
创建新的消息队列或取得已存在的消息队列
int msgget(key_t key,int msgflg);
key:可认为是端口号,由ftok()函数生成;
msgflg:IPC_CREAT:如果IPC不存在,生成新的IPC资源,否则打开旧的资源,单独使用IPC_CREAT,msgget()返回的是新建共享内存的标识符或已有共享内存的操作符;
IPC_EXCL:只有在共享内存不存在时,再建立新的共享内存。它本身没有意义,和IPC_CREAT一起使用保证消息队列是新建的,而不是打开已有的资源。
向队列中读写数据
读数据:
size_t msgrcv(int msgid,void* msgp,size_t msgsz,long msgtyp,int msgflg)
msgid:消息队列标识码;
msgp:指向消息缓冲区的指针,用来暂存接收和发送消息;
msgsz:消息大小;
msgtyp:从消息队列读取消息的形态,为0时,所有消息将被读取;
msgflg:指示核心程序在队列为空时的行动。如果和IPC_NOWAIT合用时,表示读(空时)或写(满时)不会等待,立即返回-1,并设定错 误码为ENOMSG,当msgflg为零时,则会出现阻塞等待的处理模式。
设定消息队列属性:
int msgctl(int msgqid,int cmd,struct msgid_ds* buf);
参数:msgctl系统调用对msgqid标识的消息队列执行cmd操作,系统定义了3种cmd操作:
IPC_STAT:该命令用来获取消息队列对应的msgqid_ds数据结构,并将其保存到buf指向的地址空间
IPC_SET:用来设置消息队列的属性,要设置的属性保存在buf中
IPC_RMID:从内核中删除msgqid标识的消息队列
相关指令:
ipcs -q :查看系统中消息队列
ipcrm -q + msgid :删除消息队列
//client#include<stdio.h>#include<stdlib.h>#include<sys/msg.h>#include<sys/types.h>#include<sys/ipc.h>#include<string.h>#define MSGKEY 1024struct msgstru{ long msgtype; char msgtext[2048];};int main(){ struct msgstru msgs; int msg_type; char str[256]; int ret_value; int msgid; msgid = msgget(MSGKEY,IPC_EXCL); if(msgid < 0) { msgid = msgget(MSGKEY,IPC_CREAT|0666); if(msgid < 0) { printf("failed to creat msgqueue!!!\n"); exit(-1); } } while(1) { printf("input message type:"); scanf("%d",&msg_type); printf("%d\n",msg_type); if(msg_type == 0) { break; } printf("input message to be sent:"); scanf("%s",str); msgs.msgtype = msg_type; strcpy(msgs.msgtext,str); //send ret_value = msgsnd(msgid,&msgs,sizeof(struct msgstru),IPC_NOWAIT); if(ret_value < 0) { printf("msgsnd() write msg failed"); exit(-1); } } msgctl(msgid,IPC_RMID,0);//del return 0;}
//server#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#define MSGKEY 1024struct msgstru{ long msgtype; char msgtext[2048];};void childproc(){ struct msgstru msgs; int msgid,ret_value; char str[512]; while(1) { msgid = msgget(MSGKEY,IPC_EXCL); if(msgid < 0) { printf("msg not existed!!!\n"); sleep(3); break; } ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0); printf("text = [%s] pid = [%d]\n",msgs.msgtext,getpid()); } return;}int main(){ int i,cpid; for(i=0;i<5;i++) { cpid = fork(); if(cpid < 0) { printf("fork failed\n"); } else if(cpid == 0) childproc(); } return 0;}
- 进程通信2——消息队列
- Linux进程通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- 进程间通信——消息队列
- Linux 进程通信—消息队列
- 进程间通信—消息队列
- 前端自动化构建入门6-使用webpack改造我们的react应用
- spring mvc 文件上传
- 立体匹配---TAD算法
- vim 配置
- 面试题 10: 二进制中1的个数
- 进程通信2——消息队列
- PHP判断上传图片的类型
- git的分支管理
- MySql命令
- java的IO之打印流
- Eclipse恢复package窗口
- mac下安装powerline美化终端窗口
- android_brightness_resolving
- jdbc操作sql server数据库的基本操作以及一些问题