设为首页 加入收藏

TOP

Linux进程间通信之消息队列总结(一)
2018-05-21 15:49:01 】 浏览:159
Tags:Linux 进程 通信 消息 队列 总结

  一、系统V IPC


  三种系统V IPC:消息队列、信号量以及共享内存(共享存储器)之间有很多相似之处。


  每个内核中的 I P C结构(消息队列、信号量或共享存储段)都用一个非负整数的标识符( i d e n t i f i e r )加以引用。



  无论何时创建I P C结构(调用m s g g e t、 s e m g e t或s h m g e t) ,都应指定一个关键字(k e y),关键字的数据类型由系统规定为 k e y _ t,通常在头文件< s y s / t y p e s . h >中被规定为长整型。关键字由内核变换成标识符。


  以上简单介绍了IPC,对接下来介绍的消息队列、信号量和共享内存有助于理解。


  二、消息队列


  1、简介


  消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。我们将称消息队列为 “队列”,其标识符为“队列 I D”。 m s g g e t用于创建一个新队列或打开一个现存的队列。 m s g s n d用于将新消息添加到队列尾端。每个消息包含一个正长整型类型字段,一个非负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给 m s g s n d。 m s g r c v用于从队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息。


  2、函数介绍


ftok函数


#include <sys/types.h>
 #include <sys/ipc.h>


key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'
功能:生成一个key(键值)


msgget函数


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


int msgget(key_t key, int msgflg);


功能:创建或取得一个消息队列对象
 返回:消息队列对象的id 同一个key得到同一个对象
 格式:msgget(key,flag|mode);
 flag:可以是0或者IPC_CREAT(不存在就创建)
mode:同文件权限一样


msgsnd函数


int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:将msgp消息写入标识为msgid的消息队列
msgp:
struct msgbuf {
 long mtype; /* message type, must be > 0 */消息的类型必须>0
 char mtext[1]; /* message data */长度随意
};


msgsz:要发送的消息的大小 不包括消息的类型占用的4个字节
msgflg: 如果是0 当消息队列为满 msgsnd会阻塞
 如果是IPC_NOWAIT 当消息队列为满时 不阻塞 立即返回


返回值:成功返回id 失败返回-1


msgrcv函数


ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
 int msgflg);


功能:从标识符为msgid的消息队列里接收一个指定类型的消息 并 存储于msgp中 读取后 把消息从消息队列中删除
msgtyp:为 0 表示无论什么类型 都可以接收
msgp:存放消息的结构体
msgsz:要接收的消息的大小 不包含消息类型占用的4字节
msgflg:如果是0 标识如果没有指定类型的消息 就一直等待
 如果是IPC_NOWAIT 则表示不等待


msgctl函数


int msgctl(int msqid, int cmd, struct msqid_ds *buf);
 msgctl(msgid,IPC_RMID,NULL);//删除消息队列对象


  程序2-2将简单演示消息队列:


  ---  snd.c  ---


#include "my.h"


typedef struct{
    long type;
    char name[20];
    int age;
}Msg;


int main()
{
    key_t key = ftok("/home/liudw",'6');
    printf("key:%x\n",key);


    int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);
    if(msgid<0)
    { 
        perror("msgget error!");
        exit(-1);
    } 


    Msg m;
    puts("please input your type name age:");
    scanf("%ld%s%d",&m.type,m.name,&m.age);
    msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),0);


    return 0;
}


---  rcv.c  ---


#include "my.h"
 
typedef struct{
    long type;
    char name[20];
    int age;
}Msg;


int main()
{
    key_t key = ftok("/home/liudw",'6');
    printf("key:%x\n",key);


    int msgid = msgget(key,O_RDONLY);
    if(msgid<0)
    { 
        perror("msgget error!");
        exit(-1);
    } 


    Msg rcv;
    long type;
    puts("please input type you want!");
    scanf("%ld",&type);


    msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);
    printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);


    msgctl(msgid,IPC_RMID,NULL);
  &nbs

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇关于 Python 迭代器协议深入理解 下一篇Shell编程基础之逻辑运算理解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目