免费注册 查看新帖 |

Chinaunix

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

进程间通讯--消息队列 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-04 10:48 |只看该作者 |倒序浏览
                    进程间通讯--消息队列


1.  创建消息队列
       #include sys/types.h>
       #include sys/ipc.h>
       #include sys/msg.h>
       int msgget(key_t key, int msgflg);
                   成功返回队列ID,失败返回-1。
参数
说明
key
创建/打开队列key值,由ftok产生,可以直接给常量
msgflg
创建/打开方式IPC_CREAT、IPC_EXCL、IPC_NOWAIT
            通常是msgflg =IPC_CREAT| IPC_EXCL|0666,意思是若不存在key值的队列则创建,否则如果存在则打开队列,0666意思与一般文件权限一样,XXX-本用户,同组用户,其他用户的读写执行的权限。
       # include sys/types.h>
       # include sys/ipc.h>
       key_t ftok(const char *pathname, int proj_id);
//获取pathname相对应的一个键值, pathname必须是存在并且可读取的文件,proj_id表示序号,用来区别同时的存在文件。成功返回key值,失败返回-1。
           
2.  队列读写
       #include sys/types.h>
       #include sys/ipc.h>
       #include sys/msg.h>
a)         读取数据――阻塞读取消息队列,直到解除阻塞。
ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);
参数
说明
msqid
已打开的消息队列id
msgp
接收存放的消息队列缓存结构
msgsz
消息数据长度
msgtyp
消息类型。=0 读取队列中第一个数据。
msgflg
读取标志通常使用IPC_NOWAIT:即没有满足条件的消息,立即返回,此时,错误代码errno=ENOMSG
IPC_EXCEPT:与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息
MSG_NOERROR:截断超长数据
缓冲内容结构如下:
struct msgbuf {
long mtype;    /* 消息类型 must be > 0 */
char mtext[1]; /* 消息数据 这里只是一个数组的首地址,并非是只有一个字符 */
            };
msgrcv()解除阻塞的条件三个条件:
1.  消息队列中有了满足条件的消息(或使用了);
2.  msqid代表的消息队列被删除;
3.  调用msgrcv()的进程被信号中断;
a)         发送数据
int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
参数
说明
msqid
已打开的消息队列id
msgp
发送存放的消息队列缓存结构
msgsz
消息数据长度
msgflg
消息类型。=0 读取队列中第一个数据。



3.  消息队列控制
       #include sys/types.h>
       #include sys/ipc.h>
       #include sys/msg.h>   
       int msgctl(int msqid, int cmd, struct msqid_ds *buf);
          成功返回0,失败返回-1。
参数
说明
msqid
已打开的消息队列id
cmd
控制类型选项
IPC_STAT:取得队列状态
IPC_SET:设置队列属性
IPC_RMID:删除消息队列
buf
存放队列的属性结构

       队列属性如下:
struct msqid_ds
{
  struct ipc_perm msg_perm; /* structure describing operation permission */
  __time_t msg_stime; /*最后一次发送消息的时间 */
  unsigned long int __unused1; /*保留*/
  __time_t msg_rtime; /* 最后一次接收数据时间 */
  unsigned long int __unused2;     /*保留*/
  __time_t msg_ctime; /* 最后修改时间 */
  unsigned long int __unused3; /*保留*/
  unsigned long int __msg_cbytes; /* 当前队列字节数 */
  msgqnum_t msg_qnum; /* 当前队列的消息数 */
  msglen_t msg_qbytes; /* 队列中容量 */
  __pid_t msg_lspid; /* 最后发送消息的进程号 */
  __pid_t msg_lrpid; /* 最后接收队列的进程号*/
  unsigned long int __unused4; /*保留*/
  unsigned long int __unused5; /*保留*/
};
4.例子:
#include sys/types.h>
#include sys/msg.h>
#include unistd.h>
#define msgkey 0x11000001
struct msg_buf
    {
        int mtype;
        char data[255];
    };

int main()
{
        key_t key;
        int msgid;
        int ret;
        struct msg_buf msgbuf;

        key=ftok("/tmp/1",'a');
        printf("key =[%x]\n",key);
        //msgid=msgget(key,IPC_CREAT|IPC_EXCL|0666); /*通过文件对应*/
        msgid=msgget(msgkey,IPC_CREAT|IPC_EXCL|0666);/*或者取常量*/
        if(msgid==-1)
        {
                printf("create error\n");
                return -1;
        }

        msgbuf.mtype = getpid();
        strcpy(msgbuf.data,"test haha");
        ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);
        if(ret==-1)
        {
                printf("send message err\n");
                return -1;
        }

        memset(&msgbuf,0,sizeof(msgbuf));
        ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);
        if(ret==-1)
        {
                printf("recv message err\n");
                return -1;
        }
        printf("recv msg =[%s]\n",msgbuf.data);

        ret=msgctl(msgid,IPC_RMID,NULL);//删除消息队列
        if(ret==-1)
        {
                printf("del msg err\n");
                return -1;
        }

}


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP