Linux-进程间通信(消息对列)

今天来介绍IPC通信的第一种方式:消息对列

由于进程具有独立性,要想两个进程之间有数据的往来,就必须让两个不相干的进程看到同一块资源。前面有讲到管道,也是一种公共资源。现在,我们介绍一种另一种公共资源:消息对列

消息对列,顾名思义,想必看到的公共资源可能就是一种队列。这种队列满足数据结构里队列的特点:先进先出。

消息对列提供了一个进程向另一个进程发送一块数据快的通信方法,注意,是以块为基本单位,前面的管道是以字节流为基本单位。

每个数据块都被认为是由类型的。接收者进程接受数据块可以有不同的类型值,比如可以是结构体型。
每个消息 队列的最大长度是上限的(MSGMAX),每个消息队列的总的字节数也是有上限的(MSGMNB),系统的消息队列总数也是有上线的(MSGMNI),
Linux-进程间通信(消息对列)_第1张图片

为了便于理解,我画了一个简图
Linux-进程间通信(消息对列)_第2张图片

认识消息队列结构

  • 操作系统为每个IPC对象都维护了一个数据结构

查看命令:

[zyc@localhost /]$ cat ./usr/include/linux/ipc.h

Linux-进程间通信(消息对列)_第3张图片

  • 查看消息队列结构

[zyc@localhost /]$ cat ./usr/include/linux/msg.h

Linux-进程间通信(消息对列)_第4张图片
Linux-进程间通信(消息对列)_第5张图片

消息队列函数

msgget函数

功能:创建和访问消息队列
原型:


 #include 
 #include 
 #include 
int msgget(key_t key, int msgflg);

参数:
    key:某个消息队列的名字
    msgflg:有九个权限标识位组成,他们的用法和创建文件时使用的mode模式是一样的
返回值:
    成功返回一个非负整数,即该消息队列的识别码,即msgid,给用户看。失败返回-1

这里解释一下标识位

IPC_CREAT:如果文件不存在,则创建一个新文件,如果存在,把存在的文件描述符返回
IPC_EXCL:没有任何实际意义,只在创建时使用,与IPC_CREAT进行或运算:IPC_CREAT|EXCL,则会创建一个全新的文件。

再解释一下 key,通过“ftok”函数获得。函数调用成功时,即通过它,就可以找到消息对列。

下面来看ftok函数介绍

#include 
#include 
key_t ftok(const char *pathname, int proj_id);

作用:获得消息对列标识符。两个互相独立的进程要进行通信,就必须都可以看到这个标志符。进程A和进程B都可以看到。

参数自己定制,一般定义在头文件中,采用宏定义方式。一般路径采用当前路径,proj_id设置0x666

返回值:成功返回消息对列标志符(给内核看),失败返回-1。

msgctl函数

作用:消息对列的控制函数
原型:

#include 
#include 
#include 

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

参数
    msqid:msgget函数的返回值,即消息队列识别码
    cmd:有三个动作
返回值
    成功返回0,失败返回-1

cmd的三个动作:

命令 说明
IPC_STST
IPC_SET
IPC_RMID 删除消息队列

msgsend函数

功能:把一条消息加入消息对列中
原型

#include 
 #include 
  #include 

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:
    msgid:由msgget函数返回的消息对列标志码
    msgp:,是一个指针指向即将发送的消息
    msgsz:是msgp指向的消息队列长度
    msgflg:控制着当前消息对列到达系统上限即将发生的事情。
    msgflg==IPC+NOWAIT表示对列不等待。返回EAGAIN错误。
返回值:成功返回0,失败返回-1

1:消息结构在两方面受到制约:

  • 他必须小于系统规定的上限值;
  • 它必须以一个long int长整数开始,接受者将按照这个长整数确定消息的类型

2,消息结构参考如下
这里写图片描述

msgrcv函数

功能:从一个消息队列中接收消息

#include 
#include 
#include 
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:
    msgid:由msgget函数返回的消息对列标志码

    msgp:,是一个指针指向即将发送的消息
    msgsz:是msgp指向的消息队列长度
    msgtype:他可以实现接收优先级的简单形式
    msgflg:控制着消息队列中没有相应类型消息可供接收时将要发生的事情。
返回值:
    成功返回0,失败返回-1

mytype=0:返回队列第一条消息
mytype>0:返回队列第一条类型等于中mytype的消息
mytype<0:返回队列中第一条类型小于mytype绝对值的消息,并且是满足条件的消息类型最小消息。
mytype=IPC_NOWAIT,队列没有消息不等待,返回ENOMSG错误
mytype=MSG_MOERROR,消息超过msgsize是将会被截断。
mytype>0且msgflg=MSG_EXCEPT,接受类型不等于msgtype的第一条消息。

下面我们将要来编写实际代码来实现基于消息对列的进程间通信。

ipcs命令和ipcrm命令

ipcs 显示IPC资源

Linux-进程间通信(消息对列)_第6张图片



ipcs -q :查看已存在消息对列
ipcrm -q (msgid)    :删除指定消息对列

你可能感兴趣的:(操作系统)