天天看點

消息隊列程式設計

一 消息隊列

  消息隊列就是一些消息的清單,使用者可以在消息隊列中添加消息和讀取消息燈。消息隊列具有一定的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);	
    }
}
           

運作結果:

消息隊列程式設計
消息隊列程式設計