System V 消息队列

System V 消息队列(1

一、函数

头文件列表

<sys/types.h>
<sys/ipc.h>
<sys/msg.h>

 

 

msgget

原型

int msgget(key_t key, int oflag);

函数功能

创建一个新的消息队列或者访问一个已存在的消息队列。

参数

key可以为IPC_PRIVATE,表示创建一个新队列;

oflag可以为IPC_CREAT, IPC_EXCL, O_RDONLY...,创建一个新队列时,会初始化msqid_ds

返回值

成功返回非负整数;失败返回-1,设置errno

 

 

 

 

 

msgsnd

原型

int msgsnd(int msqid, const void *ptr, size_t len, int flag);

函数功能

给描述符msqid指向的消息队列发送消息,大小为len,内容存放在ptr.

参数

ptr指向的数据定义成以下类型

typedef struct {

long mtype;      /* 消息类型 */

char mdata[100]; /* 消息内容 */

...

}msg;

len=sizeof(msg) - sizeof(long)

flag0或者IPC_NOWAITIPC_NOWAIT设置不阻塞

返回值

成功返回0;失败返回-1,设置errno

 

 

 

 

 

 

 

msgrcv

原型

ssize_t msgrcv(int msqid, void *ptr, size_t len, long type, int

flag);

函数功能

从队列读取消息

参数

ptr指向msg结构体

len指示msg中数据的长度

type的值:

0:返回队列中最早的消息

>0:返回类型为type的第一个消息

<0:返回类型值<=|type|的消息中类型值最小的第一个消息

flag的值:

0:没有所要求取的消息时,阻塞

IPC_NOWAIT:不阻塞

IPC_NOERROR:当所接收消息的数据部分大于len参数时,截断数据部分,不返

回错误,否则返回一个E2BIG错误

返回值

成功返回消息的字节数,失败返回-1

 

 

 

 

 

 

msgctl

原型

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

函数功能

控制队列操作

参数

cmd的值:

IPC_STAT: 返回队列的当前msqid_ds结构体

IPC_SET:  设置队列的msqid_ds的部分成员:msg_perm.{uid,gid,mode}

IPC_RMID: 删除消息队列,里面的任何消息都被丢弃

IPC_INFOMSG_INFOMSG_STATlinux所特有

返回值

成功返回0,失败返回-1

 

 

 

 

二、系统限制

每个消息的最大字节数
/proc/sys/kernel/msgmax 65536
队列的最大字节数
/proc/sys/kernel/msgmnb 65536
系统范围的最大队列数
/proc/sys/kernel/msgmni 16


一、msgctl程序举例

#include <sys/ipc.h>

#include <sys/msg.h>

#include <sys/types.h>

#include <stdio.h>

#define SVMSG_MODE 0660

struct msgbuf{

  int msgtype;  //消息的类型

  char msgdata[100];  //消息的数据

};

 

int main(int argc, char **argv)

{

int msqid;  //返回创建消息队列的编号

struct msqid_ds info;

/*

消息队列状态

struct msqid_ds

  {

    struct msqid_ds {

    struct ipc_perm msg_perm;

    struct msg *msg_first;      //* first message on queue,unused

    struct msg *msg_last;       //* last message in queue,unused

    __kernel_time_t msg_stime;  //* last msgsnd time

    __kernel_time_t msg_rtime;  //* last msgrcv time

    __kernel_time_t msg_ctime;  //* last change time

    unsigned long  msg_lcbytes; //* Reuse junk fields for 32 bit

    unsigned long  msg_lqbytes; //* ditto

    unsigned short msg_cbytes;  //* current number of bytes on queue

    unsigned short msg_qnum;    //* number of messages in queue

    unsigned short msg_qbytes;  //* max number of bytes on queue

    __kernel_ipc_pid_t msg_lspid;   //* pid of last msgsnd

    __kernel_ipc_pid_t msg_lrpid;   //* last receive pid

};

*/

struct msgbuf buf;  //存放消息的信息

 

msqid = msgget(IPC_PRIVATE,SVMSG_MODE|IPC_CREAT);

//两个参数,第一个是表示创建,第二个是flag标记符号

 

//给消息队列的内容和消息类型赋值

buf.msgtype=1;

buf.msgdata[0]=1;

 

msgsnd(msqid, &buf, 1, 0);

//发送编号为msqid的消息的内容长度为1的消息,类型为0,结构体是buf

 

msgctl(msqid, IPC_STAT, &info);

//操作编号为msqid的消息,操作对象为当前结构体,结构体的内容为info

 

printf("read-write:%03o, cbytes=%luqnum=%lu,qbytes=%lu\n",

info.msg_perm.mode &0777,info.msg_cbytes, info.msg_qnum,info.msg_qbytes);

system("ipcs -q");  //显示所有消息队列

msgctl(msqid,IPC_RMID,NULL);

 

exit(0);

 

return 0;

}

 

二、创建、发送、接收程序举例

#include <sys/ipc.h>

#include <sys/msg.h>

#include <sys/types.h>

#include <stdio.h>

#include <getopt.h>

#define SVMSG_MODE 0660

#define MAXMSG 255

 

 

//定义了消息的类型和内容

struct msgbuf {

    int msgtype;

    char msgdata[100];

 

};

 

int main(int argc, char **argv)

{

    int msqid,receive;   //返回的是消息队列的编号

    struct msqid_ds info,info2;  //定义消息的状态的结构体,在创建的时候会初始化

    struct msgbuf buf,buf2;  //定义消息类型和内容结构体对象

 

    msqid = msgget(IPC_PRIVATE,SVMSG_MODE|IPC_CREAT);  //创建消息

 

    buf.msgtype = 1;    //消息类型和内容赋值

    buf.msgdata[0]=1;

 

    msgsnd(msqid,&buf,1,0);  //发送消息

 

    receive=msgrcv(msqid,&buf2,MAXMSG,1,0);  //接受消息,并且把消息的编号记住

 

    printf("read %d bytes,type= %ld\n",receive,buf2.msgtype);  //读出消息的相关信息

 

    system("ipcs -q");   //显示进程当前的消息信息

    return 0;

}

 

三、一个服务器和客户端的程序举例

服务端

#include <sys/ipc.h>

#include <sys/msg.h>

#include <sys/types.h>

#include <stdio.h>

#include <getopt.h>

#include <stdlib.h>

#include <errno.h>

#define SVMSG_MODE 0660

#define MSQ_KEY1 1234L

#define MSQ_KEY2 2345L

#define MAXMSGDATA 255

 

struct msg_t{

int mtype;

int mlen;

char mdata[100];

};

void server(int rdid, int wrid) {

         FILE *fp;

         char *ptr;

         pid_t pid;

         ssize_t n;

         struct msg_t msg;

         for (;;) {

                   msg.mtype = 1;

                   if ((n = msgrcv(rdid, &msg,MAXMSGDATA,1,0)) == 0) {

                            printf("pahtname missing");

                            continue;

                   }

                   msg.mdata[n] = '\0';

                   if ((ptr = strchr(msg.mdata' ')) == NULL) {

                            printf("bogus request: %s\n", msg.mdata);

                            continue;

                   }

                   *ptr++ = '\0';

                   pid = atoi(msg.mdata);

                   msg.mtype = pid;

                   if ((fp = fopen(ptr, "r")) == NULL) {

                            snprintf(msg.mdata + n, sizeof(msg.mdata) - n, "can't open, %s\n",

                                               strerror(errno));

                            msg.mlen = strlen(ptr);

                            memmove(msg.mdata, ptr, msg.mlen);

                            msgsnd(wrid, &msg,msg.mlen,0);

                   } else {

                            while (fgets(msg.mdata, MAXMSGDATA, fp) != NULL) {

                                     msg.mlen = strlen(msg.mdata);

                                     msgsnd(wrid, &msg,msg.mlen,0);

                            }

                            fclose(fp);

                   }

                   msg.mlen = 0;

                   msgsnd(wrid, &msg,msg.mlen,0);

         }

}

 

int main(int argc, char *argv[]) {

         int rdid, wrid;

         rdid = msgget(MSQ_KEY1, 0644 | IPC_CREAT);

         wrid = msgget(MSQ_KEY2, 0644 | IPC_CREAT);

         server(rdid, wrid);

         system("ipcs -q");

         printf("OK");

         exit(EXIT_SUCCESS);

}

 

 

 

客户端

/*

 * cient.c

 *

 *  Created on: Sep 15, 2011

 *      Author: tanciping

 */

#include <sys/ipc.h>

#include <sys/msg.h>

#include <sys/types.h>

#include <stdio.h>

#include <getopt.h>

#include <stdlib.h>

#include <errno.h>

#define SVMSG_MODE 0660

#define MSQ_KEY1 1234L

#define MSQ_KEY2 2345L

#define MAXMSGDATA 255

#define STDOUT_FILEENO "/home/tanciping/Desktop/xx"

struct msg_t {

         int mtype;

         int mlen;

         char mdata[100];

};

void client(int rdid, int wdid) {

 

         size_t len;

         ssize_t n;

         char *ptr;

         struct msg_t msg;

         snprintf(msg.mdata,MAXMSGDATA,"%ld",(long)getpid());

         len = strlen(msg.mdata);

         ptr=msg.mdata+len;

         fgets(ptr,MAXMSGDATA-len,stdin);

         len = strlen(msg.mdata);

         if(msg.mdata[len-1]=='\n')

                   len--;

         msg.mlen=len;

         msg.mtype=1;

         msgsnd(wdid,&msg,msg.mlen,0);

         while((n==msgrcv(rdid,&msg,MAXMSGDATA,msg.mtype,0))>0)

                   write(STDOUT_FILEENO,msg.mdata,n);

 

}

 

int main() {

         int rdid,wrid;

         rdid = msgget(MSQ_KEY1, 0644 | IPC_CREAT);

         wrid = msgget(MSQ_KEY2, 0644 | IPC_CREAT);

         client(rdid, wrid);

         system("ipcs -q");

         printf("OK");

         exit(EXIT_SUCCESS);

 

}

 

 

 

四、消息队列的限制

msgmax 每个消息的最大字节数

msgmnb 任何一个消息队列上的最大字节数

msgmni 系统范围的最大消息队列数

msgtql 系统范围的最大消息数


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值