热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>内核研究>

进程间通讯--消息队列

来源: 作者: 时间:2007-11-19 Tag: 点击:
 
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_CREATIPC_EXCLIPC_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;
        }
 
}



相关文章:
精通initramfs构建step by step
Linux利用kexec迅速切换内核
进程上下文VS中断上下文
内核通知链 学习笔记
linux spi子系统驱动分析
menuconfig 配置选项
《Linux操作系统内核实习》之练习一
udev详解
什么叫微内核,宏内核?
Linux 信号signal处理机制
开发简单的 Linux2.6 内核模块
删除内核的perl脚本
Linux2.6内核usb gadget驱动移植
GCC hacks in the Linux kernel
iomem
kernel学习的想法
让自己的驱动支持udev
linux内核编译步骤
内核的等待队列
Linux内核wait_queue深入分析
升级和删除内核
SD卡驱动分析2
Linux Kernel VDSO本地权限提升漏洞
内核中的TCP的追踪分析-15-TCP(IPV4)的客户端与
linux 2.6内核可加载模块的编译
内核模块HelloWorld
在环回接口上发送一个数据报
ARP初始化
1分钟编译FreeBSD内核
linux设备模型之uart驱动架构分析