消息对列

命令:查看消息对列 ipcs -q

    查看共享内存  ipcs -s

    查看信号量   ipcs -s

    三个同时查看 ipcs

    删除消息对列  ipcrm -q  msgid

    删除消息对列  ipcrm -q  msgid

    删除消息对列  ipcrm -q  msgid

一.管道则只能传送无格式字节流,
     消息队列(也叫报文队列)客服了这些缺点:
     消息队列就是一个消息的链表。
     可以把消息看作一个记录,具有特定的格式。

二.   在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。这跟管道和FIFO是相反的,对后两者来说,除非读出者已存在,否则先有写入者是没有意义的。

管道和FIFO都是随进程持续的,XSI IPC(消息队列、信号量、共享内存)都是随内核持续的。

当一个管道或FIFO的最后一次关闭发生时,仍在该管道或FIFO上的数据将被丢弃。消息队列,除非内核自举或显式删除,否则其一直存在。

创建消息对列:

1.创建一个key,使用函数ftok()

msgget函数

函数msgget,其功能是打开一个现存队列或创建一个新队列。

#include <sys/msg.h>

int  msgget (key_t key,  int oflag) ;

返回值是一个整数标识符,其他三个msg函数就用它来指代该队列。它是基于指定的key产生的,而key既可以是ftok的返回值,也可以是常值IPC_PRIVATE。

oflag是读写权限的组合(用于打开时)。它还可以是IPC_CREATE或IPC_CREATE | IPC_EXCL(用于创建时)。(创建时如果存在则报错)

msgsnd函数

使用msgsnd打开一个消息队列后,我们使用msgsnd往其上放置一个消息。

#include <sys/msg.h>

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

1.   msqid是由msgget返回的标识符。

2.   ptr是一个结构指针,该结构具有如下模板(我们需要按这个模板自己定义结构体)

struct mymesg {
    long  mtype ;     //消息类型(大于0)
    char  mtext[512] ;  //消息数据
} ;

 //结构体的名字和其中变量名都由我们自己确定,我们只要按照这个模板定义即可。

消息数据mtext中,任何形式的数据都是允许的,无论是二进制数据还是文本,内核根本不解释消息数据的内容。(我们可以在消息的数据部分 再分割一部分 根据需要定义自己的通信协议)

3. 参数length指定了待发送消息数据部分的长度。

4. 参数flag的值可以指定为IPC_NOWAIT。这类似于文件IO的非阻塞IO标志。若消息队列已满,则指定IPC_NOWAIT使得msgsnd立即出错返回EAGAIN。

如果没有指定IPC_NOWAIT,则进程阻塞直到下述情况出现为止:①有空间可以容纳要发送的消息 ②从系统中删除了此队列(返回EIDRM“标识符被删除”)③捕捉到一个信号,并从信号处理程序返回(返回EINTR)

msgrcv函数

使用msgrcv函数从某个消息队列中读出一个消息。

#include <sys/msg.h>

ssize_t  msgrcv (int msqid,  void* ptr,  size_t length,  long type,  int flag) ;

参数ptr指定所接收消息的存放位置。参数length指定了数据部分大小(只想要多长的数据)

参数type指定希望从队列中读出什么样的消息。

type == 0 返回队列中的第一个消息

type > 0  返回队列中消息类型为type的第一个消息

type < 0  返回队列中消息类型值小于或等于type绝对值的消息,如果这种消息有若干个。则取类型值最小的消息。

(如果一个消息队列由多个客户进程和一个服务器进程使用,那么type字段可以用来包含客户进程的进程ID)

参数flag可以指定为IPC_NOWAIT,使操作不阻塞。

msgctl函数

msgctl函数提供在一个消息队列上的各种控制操作。

#include <sys/msg.h>

int  msgctl (int msqid,  in cmd,  struct msqid_ds * buff) ;

参数cmd说明对由msqid指定的队列要执行的命令:

IPC_STAT :取此队列的msqid_ds结构,并将它存放在buf指向的结构中。

IPC_SET  :按由buf指向结构中的值,设置与此队列相关结构中的字段。

IPC_RMID:从系统中删除该消息队列以及仍在该队列中的所有数据。

(这三条命令也可用于信号量和共享存储)

 http://www.cnblogs.com/fangshenghui/p/4039866.html

猜你喜欢

转载自www.cnblogs.com/Lune-Qiu/p/9365072.html