Linux高级进程间通信:消息队列

enter.c:

/* enter----place an object into queue */

#include"q.h"
#include<string.h>

int warn(char *s);//error process
int init_queue(void);//initalize queue

int enter(char *objname,int priority)
{
    int len,s_qid;
    struct q_entry s_entry;    //structure to hold message 

    /* validate name length,priority level */

    if((len=strlen(objname))>MAXOBN)
    {
    warn("name too long");
        return (-1);
    }

    if(priority>MAXPRIOR||priority<0)
    {
        warn("invalid priority level");
        return (-1);
    }

    /* initialize message queue as necessary */
    if((s_qid=init_queue())==-1)
    {
        return (-1);
    }

    /*initilize s_entry */
    s_entry.mtype=(long)priority;
    strncpy(s_entry.mtext,objname,MAXOBN);

    /*send message,waiting if necessary */

    if(msgsnd(s_qid,&s_entry,len,0)==-1)
    {
        perror("msgsnd failed");
        return (-1);
    }
    else
    {
        return (0);
    }
}





q.h:

/*q.h----header for message facility example */
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include<errno.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

#define QKEY   (key_t)0105   /* identifying key for queue */
#define QPERM   0660         /*permissions for queue      */
#define MAXOBN  50           /* maximum length of obj.name*/
#define MAXPRIOR 10          /*maximum priority level  */

struct q_entry
{
    long mtype;
    char mtext[MAXOBN+1];
};



queue.c:

/* error process */

#include "q.h"
#include<errno.h>

int warn(char *s)
{
        fprintf(stderr,"warning:%s/n",s);
            return 1;
}

/* init_queue-----get queue identifier*/
int init_queue(void)
{
        int queue_id;

            /*attempt to create or open message queue */
            if((queue_id=msgget(QKEY,IPC_CREAT|QPERM))==-1)
                    {
                                perror("msgget failed");
                                    }

                return (queue_id);
}



etest.c:

/* etest -----enter object name on queue */

#include "q.h"

int warn(char *s);
int init_queue(void);
int main(int argc,char **argv)
{
  int priority;

    if(argc!=3)  //command args number 
    {
        fprintf(stderr,"usage:%s objname priority /n",argv[0]);
    }
    if((priority=atoi(argv[2]))<0||priority>MAXPRIOR)//priority 
    {
        warn("invalid priority");
        exit (2);
    }

    if(enter(argv[1],priority)<0)  //enter queue
    {
        warn("enter queue failure");
        exit(3);
    }

    exit(0);



}



serve.c:

/* serve----serve object with highest priority on the queue */

#include"q.h"

int proc_obj(struct q_entry *msg);//print message

int serve(void)
{
    int mlen,r_qid;
    struct q_entry r_entry;//receive entry

    /*initilize message queue as necessary */

    if((r_qid=init_queue())==-1)
    {
        return (-1);
    }

    /*get and process next message,waiting if necessary */

    for(;;)
    {
        if((mlen=msgrcv(r_qid,&r_entry,MAXOBN,(
                            -1*MAXPRIOR),MSG_NOERROR))==1)
      {
                perror("msgrcv failed");
                return (-1);
            }
        else
        {
            /*make sure we've a string */
            r_entry.mtext[mlen]='/0';//why no MAXOBN?

            /* process object name */
            proc_obj(&r_entry);
        }
    }
}

/* proc_obj:printf message of the object */
int proc_obj(struct q_entry *msg)
{
    printf("/npriority:%ld  name:%s  /n",msg->mtype,msg->mtext);
}




stest.c:

/* stest----simple server for queue */
#include "q.h"

int main(void)
{
    pid_t pid;

    switch(fork())
    {
        case 0:    //child
            serve();   //call message queue receive 
            break;
        case -1:
            warn("fork to start server failed");
            break;
        default:
            printf("server process pid is %d /n",pid);//print child pid

    }

    exit(pid!=-1?0:1);//??
}






jiang@jiang-linux:~/unixprog/2011323$ gcc enter.c queue.c etest.c -o etest.o
jiang@jiang-linux:~/unixprog/2011323$ gcc serve.c queue.c stest.c -o stest.o

jiang@jiang-linux:~/unixprog/2011323$ ./etest.o objname1 3   //向消息队列放入消息
jiang@jiang-linux:~/unixprog/2011323$ ./etest.o objname2 9
jiang@jiang-linux:~/unixprog/2011323$ ./etest.o objname3 1
jiang@jiang-linux:~/unixprog/2011323$ ./etest.o objname4 2
jiang@jiang-linux:~/unixprog/2011323$ ./stest.o                           //读取消息
server process pid is 11079668

priority:1  name:objname3 

priority:2  name:objname4 

priority:3  name:objname1 

priority:9  name:objname2 


使用msgctl系统调用:


/* showmsg -----show message queue details  */

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<time.h>
#include<errno.h>
#include<stdlib.h>


void mqstat_print(key_t mkey,int mqid,struct msqid_ds *mstat);

int main(int argc,char **argv)
{
       //key_t mkey;
//本来是设计从命令行接收消息队列的关键值的,但是命令行参数不知道如何输入格式,
//因此改为和前面程序一样的关键值。注释掉对命令行参数的验证和使用。
    key_t mkey=0105;
    int msq_id;
    struct msqid_ds msq_status;

/*    if(argc!=2)
    {
        fprintf(stderr,"usage:showmsg keyval/n");
        exit (1);
    }
    
*/
    /* get message queue identifier */
//    mkey=(key_t)atoi(argv[1]);
    if((msq_id=msgget(mkey,0))==-1)
    {
        perror("msgctl failed");
        exit (2);
    }

    /* get status information */
    if(msgctl(msq_id,IPC_STAT,&msq_status)==-1)
    {
        perror("msgctl failed");
        exit (3);
    }

    /* print out status information */
    mqstat_print(mkey,msq_id,&msq_status);
    exit (0);
}

void mqstat_print(key_t mkey,int mqid,struct msqid_ds *mstat)
{
    printf("/nKey:%d,msg_qid :%d/n/n",mkey,mqid);
    printf("%d message(s) on queue/n/n",(int)mstat->msg_qnum);
//ctime函数用来将time_t转换成可读的格式
    printf("Last send by proc %d at %s /n",mstat->msg_lspid,
                        ctime(&(mstat->msg_stime)));
    printf("Last receive by proc %d at %s /n",mstat->msg_lrpid,
                        ctime(&(mstat->msg_rtime)));
}


运行结果:
发送消息:
jiang@jiang-linux:~/unixprog/2011323$ ./etest.o hello 6
jiang@jiang-linux:~/unixprog/2011323$ ./etest.o hello3 7
接收消息:
jiang@jiang-linux:~/unixprog/2011323$ ./stest.o
server process pid is 10481652

priority:6  name:hello 

priority:7  name:hello3 

打印状态信息:

jiang@jiang-linux:~/unixprog/2011323$ ./showmsg.o

Key:69,msg_qid :0

0 message(s) on queue

Last send by proc 1881 at Wed Mar 23 15:48:47 2011
 
Last receive by proc 1947 at Wed Mar 23 15:52:42 2011

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值