免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 810 | 回复: 0
打印 上一主题 下一主题

UNIX网络编程卷2进程间通信读书笔记(五)—System V消息队列 (2) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-10 15:35 |只看该作者 |倒序浏览
4.
名称::
msgrcv
功能:
从队列中取出消息
头文件:
#include
#include
#inlcude
函数原形:
int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);
参数:
msqid   消息队列描述字
msgp    指向消息数据的指针
msgsz   接收消息的大小
msgtyp   请求读取的消息类型
msgflg   标志位
返回值:
若成功则为消息数据部分的长度,若出错则为-1。
      








该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。
       msqid为消息队列描述字;消息返回后存储在msgp指向的地址,msgsz指定msgbuf的mtext成员的长度(即消息内容的长度),msgtyp为请求读取的消息类型;读消息标志msgflg可以为以下几个常值的或:
       IPC_NOWAIT 如果没有满足条件的消息,调用立即返回,此时,errno=ENOMSG
       IPC_EXCEPT 与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息
       IPC_NOERROR 如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将丢失。
       msgtyp使我们可以指定想要哪一种消息:
       msgtyp==0     返回队列中的第一个消息。
       msgtyp>0       返回队列中消息类型为msgtyp的第一个消息。
       msgtyp       返回队列中消息类型值小于或等于msgtyp绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。
       当msgrcv成功返回,与消息队列相关的msqid_ds结构得到更新,以标明发出该调用的进程ID(msg_lspid),进行该调用的时间(msg_stime),并将队列中消息数(msg_qnum)减1。

7.消息队列与管道以及有名管道的比较
       消息队列与管道以及有名管道相比,具有更大的灵活性,首先,它提供有格式字节流,有利于减少开发人员的工作量;其次,消息具有类型,在实际应用中,可作为优先级使用。这两点是管道以及有名管道所不能比的。同样,消息队列可以在几个进程间复用,而不管这几个进程是否具有亲缘关系,这一点与有名管道很相似;但消息队列是随内核持续的,与有名管道(随进程持续)相比,生命力更强,应用空间更大。

       输出消息队列信息的例子:
#include  
#include
#include
#include
#define KEY 75

void msg_stat(int,struct msqid_ds);

int main()
{
int msgid;
int sflags,rflags;
struct msqid_ds msg;

struct msgbuf{
    int mtypes;
    char mtext[10];
}msg_buf;

msgid=msgget(KEY,IPC_CREAT);
msg_stat(msgid,msg);

sflags=IPC_NOWAIT;
msg_buf.mtypes=10;
msg_buf.mtext[0]=’a’;
msgsnd(msgid,&msg_buf,sizeof(msg_buf.mtext),sflags);
msg_stat(msgid,msg);

rflags=IPC_NOWAIT|MSG_NOERROR;
msgrcv(msgid,&msg_buf,4,10,rflags);
msg.msg_perm.uid=8;
msg.msg_perm.gid=8;
msg.msg_qbytes=16388;
msgctl(msgid,IPC_SET,&msg);
msg_stat(msgid,msg);
msgctl(msgid,IPC_RMID,NULL);
}

void msg_stat(int msgid,struct msqid_ds msg)
{
    msgctl(msgid,IPC_STAT,&msg);

printf("current number of bytes on queue is %d\n",msg_info.msg_cbytes); /*最后消息的类型*/
printf("number of messages in queue is %d\n",msg_info.msg_qnum);/*当前消息队列的消息数*/
printf("max number of bytes on queue is %d\n",msg_info.msg_qbytes); /*消息队列的容量*/
printf("pid of last msgsnd is %d\n",msg_info.msg_lspid);/*最后发送消息时间*/
printf("pid of last msgrcv is %d\n",msg_info.msg_lrpid); /*最后接受消息进程*/
printf("last msgsnd time is %s", ctime(&(msg_info.msg_stime)));/*最后发送消息时间*/
printf("last msgrcv time is %s", ctime(&(msg_info.msg_rtime)));/*最后接受消息时间*/
printf("last change time is %s", ctime(&(msg_info.msg_ctime)));/* 最后修改时间*/
printf("msg uid is %d\n",msg_info.msg_perm.uid); /*进程id*/
printf("msg gid is %d\n",msg_info.msg_perm.gid); /*进程组id*/
}


用消息队列实现进程间通信的例子:
/* 14_6.c客户进程*/
#include
#include
#include
#define MSGKEY 75
#define MAXLINE 100
struct msgform /*定义消息格式*/
{
long mtype; /*消息类型*/
pid_t pid; /*消息发送进程ID */
    char mtext[100];/*消息数据*/
}msg;
int msgqid;/*定义消息的id*/
void client()
{
    int i;
    msgqid=msgget(MSGKEY,0777); /*打开75#消息队列*/
    for(i=1;i>5;i++)/*循环发送5个消息*/
    {
        msg.mtype=i;
        printf(“client:”);
        fgets(msg.mtext,MAXLINE,stdin);/*把用户输入读入缓冲区*/
        msgsnd(msgqid,&msg,1024,0); /*发送消息*/
    }
    exit(0);
}
main( )
{
    client( );
}
/*14_7.c  服务器进程*/
#include
#include
#include
#define MSGKEY 75
struct msgform
{
long mtype;
pid_t pid;
    char mtext[100];
}msg;
int msgqid;
void server( )
{
    msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*创建75#消息队列*/
    do
    {
        msgrcv(msgqid,&msg,1030,0,0); /*接收消息*/
        printf(“name:%d,type:%d,date:%s\n”,msg.pid,msg.mtype,msg.mtext);
/*输出消息*/
    }
while(msg.mtype!=5);
    msgctl(msgqid,IPC_RMID,0); /*删除消息队列,归还资源*/
    exit(0);
}
main( )
{
    server( );
}
    程序client.c和server.c,分别用于消息的发送与接收.server建立一个 Key 为75的消息队列,等待其它进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出server。server每接收到一个消息后显示一句“server:输入信息”. client使用 key为75的消息队列,先后发送类型从3到1的消息,然后退出。最后一个消息,即是 server端需要的结束信号。client 每发送一条消息后显示一句 “client:要发送的消息”。
    注意: 二个程序分别编辑、编译为client与server。执行:
./server&
./client




本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/22935/showart_274958.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP