Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1485197
  • 博文数量: 181
  • 博客积分: 3308
  • 博客等级: 中校
  • 技术积分: 2227
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-03 12:03
个人简介

我是zoro

文章分类

全部博文(181)

文章存档

2015年(1)

2013年(35)

2012年(39)

2011年(50)

2010年(56)

分类: LINUX

2010-10-03 12:08:37

1.标识符和键

每个内核中的IPC结构(消息对了、信号量或共享存储段)都有一个非负整数(int型)标识符identifier)加以引用。标识符是IPC对象的内部名为使多个合作进程能够在同一IPC对象上会合,需要提供外部名。为此使用了键(key),每个IPC对象都与一个键相关联,于是键就用做为该对象的外部名。

键的数据类型是基本系统数据类型key_t,通常在头文件中被定义为长整型。键由内核变换为标识符。

产生一个键

#include

#include

key_t ftok(const char *pathname, int proj_id); //path引用一个现存文件,只使用id参数的低8位。

返回值:成功返回键,出错返回(key_t)-1

此后可以使用 IPC 对象的 get 函数(在下面说明这些函数)创建或访问指定的 IPC 对象。这些函

数共有的规则是:

•key参数为 IPC_PRIVATE 的话表示创建一个新的 IPC 对象;

•key没有被现有的 IPC 对象使用,并在参数 flag 中指定 IPC_CREAT ,也创建一个新的 IPC 对象;判定 key 是否已经被使用,可以在 flag 中指定 IPC_EXCL;

否则,get 函数则用于通过指定的 key 获得对应 IPC 对象的标识符;

访问模式

消息队列和共享内存包括“读”和“写”两种访问模式,而信号量为“读”和“更改”两种模 式。

IPC 对象的主要优点和缺点:

需要自己设计引用计数等释放对象的规则;

不属于文件范畴,不能使用文件系统的 open(2)read(2)write(2)I/O 函数,故也不能 利用已有的高级 I/O 机制并行地访问多个 IPC 对象;


2.消息队列

消息队列是消息的连接表,存放在内核中并由消息队列标识符标志。

打开一个现存队列或创建一个新队列

调用的第一个函数通常是msgget,其功能是打开一个现存队列或创建一个新队列。

#include

#include

#include

int msgget(key_t key, int msgflg);

返回值:成功返回消息队列ID,出错返回-1

The msqid_ds data structure is defined in as follows:

struct msqid_ds {

struct ipc_perm msg_perm; /* Ownership and permissions */

time_t msg_stime; /* Time of last msgsnd(2) */

time_t msg_rtime; /* Time of last msgrcv(2) */

time_t msg_ctime; /* Time of last change */

unsigned long __msg_cbytes; /* Current number of bytes in queue (non-standard) */

msgqnum_t msg_qnum; /* Current number of messages in queue */

msglen_t msg_qbytes; /* Maximum number of bytes allowed in queue */

pid_t msg_lspid; /* PID of last msgsnd(2) */

pid_t msg_lrpid; /* PID of last msgrcv(2) */

};

struct ipc_perm {

key_t __key; /* Key supplied to msgget(2) */

uid_t uid; /* Effective UID of owner */

gid_t gid; /* Effective GID of owner */

uid_t cuid; /* Effective UID of creator */

gid_t cgid; /* Effective GID of creator */

unsigned short mode; /* Permissions */

unsigned short __seq; /* Sequence number */

};

msgctl函数对队列执行多种操作。

#include

#include

#include

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

返回值:若成功返回0,出错返回-1

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

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

  • IPC_SET: 按由buf指向结构中的值, 设置与此队列相关结构中的msg_perm.uid, msg_perm.gid, msg_perm.modemsg_qbytes. 该命令只有下列两种进程可以执行:

    • 有效用户ID等于msg_perm.cuidmsg_per.uid.

    • 具有超级用户特权的进程.

  • IPC_RMID: 从系统中删除该消息队列以及仍在该队列中的所有数据. 执行权限同上.

msgsnd函数将数据放到消息队列中

#include

#include

#include

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

返回值:若成功返回0,出错返回-1


ptr参数指向一个长整型数,它包含了正的整型消息类型,其后紧跟着消息数据(若msgsz0,则无消息数据)。ptr就是一个指向msgbuf结构的指针。接收者可以使用消息类型以非先进先出的次序取消息。

struct msgbuf {

long mtype; /* message type, must be > 0 */

char mtext[msgsz]; /* message data ,of length msgsz*/

};


flag 一般为0,也可以为 IPC_NOWAIT(类似文件I/O的非阻塞I/O标志,不使用的话在队列已经满的时候将被阻塞,直到有信号被递送或 者队列腾出空间)

④msgrcv从队列中取用消息

#include

#include

#include

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

返回值:成功返回消息数据部分的长度,出错返回-1.

参数 msgtyp使我们可以指定想要哪一种消息:

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

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

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

msgrcv成功返回时, 与消息队列相关的msqid_ds结构被更新, 以指示调用者的进程ID(msg_lrpid), 调用时间(msg_rtime)和队列中的消息数(msg_qnum)1.

阅读(2339) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:ubuntu使用杂记

给主人留下些什么吧!~~