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