进程通信2——消息队列

来源:互联网 发布:java使用hbase数据库 编辑:程序博客网 时间:2024/06/07 14:08

消息队列是由链表实现的,它是基于system V标准。

特点:

  1. 双向通信;
  2. 基于消息(数据块);
  3. 不遵循“先入先出”的原则;
  4. 生命周期随内核;

创建新的消息队列或取得已存在的消息队列

        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;}
原创粉丝点击