1. 程式人生 > >訊息佇列程式設計

訊息佇列程式設計

一 訊息佇列

  訊息佇列就是一些訊息的列表,使用者可以在訊息佇列中新增訊息和讀取訊息燈。訊息佇列具有一定的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);	
    }
}

執行結果: