消息队列编程

一 消息队列

  消息队列就是一些消息的列表,用户可以在消息队列中添加消息和读取消息灯。消息队列具有一定的FIFO特性,但是它可以实现消息的随机查询,比FIFO更具有优势。同时,这些消息又是存在于内核中的,由“队列ID”来标识。

二 函数学习

三 实例

  在该实例当中,发送端发送的消息类型设置为该进程的进程号(也可以取其他值),因此接受端根据消息类型来确定消息发送者的进程号。

messagesend.c

//使用消息队列发送信息
#include <stdio.h>  
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <sys/msg.h>
#include <string.h>  

#define BUFF_SIZE 512

struct message{
    long msg_type;
    char msg_text[BUFF_SIZE];
};

void main()
{
    key_t key=0;
    int qid;
    struct message msg;
    
    if( (key=ftok(".",'a')) == -1)
    {
    	//创建键值失败
    	printf("creat key error\n");
    	
        exit(0);	
    }
    
    //创建消息队列
    /*****************************
    函数原型:int msgget(key_t key,int msgflg)
    函数参数:key 消息队列的键值,多个进程通过它访问一个消息
                  队列
              msgflg 权限标志位
    返回值:成功 返回消息队列的ID
            失败 返回-1
    *****************************/
    if((qid=msgget(key,IPC_CREAT|0666))==-1)
    {
    	printf("msgget\n",-1);
    	exit(0);    	
    }
    //打印消息队列的ID
    printf("open queue %d\n",qid);
   
    
    while(1)
    {
        printf("Enter some message to the queue:\n");
        if((fgets(msg.msg_text,BUFF_SIZE,stdin))==NULL)
        {
            printf("no message\n");
            exit(1);	
        }
        msg.msg_type=getpid();  
        

        /*****************************
        函数原型:int msgsnd(int msqid,
                             const void *msqp,
                             size_t msgsz,
                             int msgflg)
        函数参数: msqid 消息队列的id
                  msqp 指向消息结构的指针,该消息结构msgbuf通常如下
                       struct msgbuf
                       {
                       	  long mtype;  //消息类型,该结构必须从这个域开始
                       	  char mtext[];//消息正文
                       	}
                  msgsz 消息正文的字节数(不包括消息类型指针变量)
                  msgflg  IPC_NOWAIT:若消息无法立即发送,函数会立刻返回
                          0 msgsnd:调用阻塞直到发送成功为止
        返回值: 成功 0
                 失败 -1                              	
        *****************************/
        if(msgsnd(qid,&msg,strlen(msg.msg_text),0)==-1)
        {
            printf("msgsnd error\n");
            exit(0);	        	
        }
        
        if(strncmp(msg.msg_text,"quit",4)==0)
        {
            break;
        }
        
    }	

    exit(0);
		
}

messagereceive.c

#include <stdio.h>  
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <sys/msg.h>
#include <string.h>  

#define BUFF_SIZE 512

struct message{
    long msg_type;
    char msg_text[BUFF_SIZE];
};

void main()
{
    int qid;
    key_t key;
    struct message msg;	
    
    
     if( (key=ftok(".",'a')) == -1)
    {
    	//创建键值失败
    	printf("creat key error\n");
    	
        exit(0);	
    }
    
     if((qid=msgget(key,IPC_CREAT|0666))==-1)
    {
    	printf("msgget\n",-1);
    	exit(0);    	
    }
    //打印消息队列的ID
    printf("open queue %d\n",qid);
    
    do
    {   
    	/************************
    	函数原型:void *memset(void *s, int ch, size_t n);
        函数描述:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s
    	************************/
    	memset(msg.msg_text,0,BUFF_SIZE);
    	
    	
    	
    	
    	/*读取消息队列*/
    	/********************
    	函数原型:ssize_t msgrcv(int msqid,
    	                         void *msgp,
    	                         size_t msgsz,
    	                         long msgtyp,
    	                         int msgflg)
    	函数参数:msqid 消息队列的ID
    	          msgp 消息缓冲区,通msgsnd()函数的msgp
    	          msgsz 消息正文的字节数 (不包括消息类型指针变量)
    	          msgtyp 0 接受消息队列中的第一个消息
    	                 大于0 接受消息队列中第一个类型为msgtyp的消息
    	                 小于0 接受消息队列中第一个类型值不小于msgtyp绝对值且类型值最小的消息
    	          msgflg 0 msgsnd()调用阻塞直到接受一条相应类型的消息为止
    	函数返回值:成功 0
    	            失败 -1    	
    	********************/
    	if(msgrcv(qid,(void *)&msg,BUFF_SIZE,0,0)<0)
    	{
    	    printf("msgrcv\n");
    	    exit(0);	    		
    	}
    	
    	printf("the message from %d:%s",msg.msg_type,msg.msg_text);
    	
    }while(strncmp(msg.msg_text,"quit",4));
    	
    //删除消息队列
    /*
    函数原型:int msgctl(int msgqid,int cmd,struct msgqid_ds *buf)
    函数参数:msgqid 消息队列的队列id
              cmd IPC_STAT 读取消息队列的数据结构msqid_ds,并将其存储在buf指定的地址中
                  IPC_SET 设置消息队列的数据结构msqid_ds中的ipc_perm域值,这个值取自buf参数
                  IPC_RMID 从内核中删除消息队列
              buf 描述消息队列的msqid_ds结构类型变量
    返回值:
    
    */
    if(msgctl(qid,IPC_RMID,NULL)<0)
    {
        printf("msgctl\n");
        exit(0);	
    }
}

运行结果:




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值