消息队列,内存共享,信号灯

1、对消息队列的操作有下面三种类型:

(1) 打开或创建消息队列。消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的描述字,只需提供该消息队列的键值即可。

:消息队列描述字是由在系统范围内唯一的键值生成的,而键值可以看作对应系统内的一条路经。

(2)读写操作。消息读写操作非常简单,对开发人员来说,每个消息都类似如下数据结构:

struct msgbuf

{

long mtype;

char mtext[1];

}

   mtype成员代表消息类型,从消息队列中读取消息的一个重要依据就是消息的类型mtext是消息内容,当然长度不一定为1。因此,对于发送消息来说,首先预置一个msgbuf缓冲区并写入消息类型和内容,调用相应的发送函数即可;对读取消息来说,首先分配这样一个msgbuf缓冲区,然后把消息读入该缓冲区即可。

(3)获得或设置消息队列属性。消息队列的信息基本上都保存在消息队列头中,因此可以分配一个类似于消息队列头的结构,如图13-5-2所示,来返回消息队列的属性;同样可以设置该数据结构。

2、消息队列API

(1)ftok函数:用于将文件名转换成键值;

(2)msgget函数:用于创建消息队列;

(3)msgrcv函数:用于读出消息队列的数据;

(4)msgsnd函数:用于往消息队列写入数据;

(5)msgctl函数:用于控制消息队列。

3、 消息队列API

(1) ftok 函数

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

其中参数fname是指定的文件名,这个文件必须是存在的而且可以访问的。id是子序号,它是一个8bit的整数。即范围是0~255。当函数执行成功,则会返回key_t键值,否则返回-1。在一般的UNIX中,通常是将文件的索引节点取出,然后在前面加上子序号就得到key_t的值。

(2) msgget 函数

int msgget(key_t key, int msgflg);

参数key是一个键值,由ftok获得;msgtag参数是一些标志位。该调用返回与健值key相对应的消息队列描述字

在以下两种情况下,该调用将创建一个新的消息队列

如果没有消息队列与健值key相对应,并且msgflg中包含IPC_CREAT标志位;

●key参数为 IPC_PRIVATE

参数 msgtag 可以为IPC_CREAT、 IPC_EXCI、 IPC_NOWAIT,或三者的或结果

返回值成功返回消息队列描述字,否则返回-1。注:参数key设置成常数IPC_PRIVATE 并不意味着其他进程不能访问该消息队只意味着即将创建新的消息队列

4、mmap()及其相关系统调用:

mmap()系统调用使得进程之间可以通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访间普通内存一样对文件进行访问,不必再调用read()write(()等操作注:实际上,mmap()系统调用并不是完全为了用于共享内存而设计的,它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而POSIX或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。

5、 信号灯

号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制。于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以改该标志。除了用于访问控制外,还可用于进程同步。信号灯有以下两种类型

(1)二值信号灯:最简单的信号灯形式,信号灯的值只能取0或1,类似于互斥锁注:二值信号灯能够实现互斥锁的功能,但两者的关注内容不同。信号灯强调共享资源要共享资源可用,其他进程同样可以修改信号灯的值;互斥锁更强调进程,占用资源的进使用完资源后,必须由进程本身来解锁

(2)计算信号灯:信号灯的值可以取任意非负值(当然受内核本身的约束)Linux 对信号灯的支持状况与消息队列一样,在 Red had 8.0发行版本中支持的是系统V的信号灯。因此,本文将主要介绍系统V信号灯及其相应API。在没有声明的情况下,以下讨论中指的都是系统V信号灯注意:通常所说的系统V信号灯指的是计数信号灯集

6、系统调用mmap()用于共享内存的两种方式:

(1)使用普通文件提供的内存映射:适用于任何进程之间;此时,需要打开或创建一个文件,然后再调用mmap()。

(2)用特殊文件提供匿名内存映射:适用于具有亲缘关系的进程之间,由于父子进程特殊的亲缘关系,在父进程中先调用mmap(),然后调用fork()。那么在调用fork(之后,子进程继承父进程匿名映射后的地址空间,同样也继承mmap()返回的地址,这样,父子进程就可以通过映射区域进行通信了。注意,这里不是一般的继承关系,一般来说,子进程单独维护从父进程继承下来的一些变量,mmap()返回的地址,却由父子进程共同维护对于具有亲缘关系的进程实现共享内存最好的方式应该是采用匿名内存映射的方式。此时,不必指定具体的文件,只要设置相应的标志即可。

7、信号灯实现原理

答:

(1)系统V信号灯是随内核持续的,只有在内核重起或者显删除一个信号灯集时,该信号灯集才会真正被删除。因此系统中记录信号灯的数据结(struct ipc_ids sem_ids)位于内核中,系统中的所有信号灯都可以在结构sem_ids中找到访问入口。

(2)图13-6-1说明了内核与信号灯是怎样建立起联系的,其struct ipc_ids sem_ids是核中记录信号灯的全局数据结构,描述一个具体的信号灯及其相关信息

8、信号灯API

答:

① semget 函数

函数定义:int semget(key_t key, int nsems, int semflag)

函数说明:参数key是一个键k获得,唯一标识一个信号灯集,用法与msgget()中的key相同;参数nsems指定打开或者新创建的信号灯集中将包含信号灯的数目;semflag参数是一些标志位。参数key和semflg的取值,以及何时打开已有信号灯集或者创建一个新的信号灯集与msgget()中的对应部分相同,不再述。 返回值:该调用返回与健值key相对应的信号灯集描述字返回值成功返回信号灯集描述字,否则返回

② Semop 函数

函数定义:int semop(int semid, struct sembuf *sops, unsigned nsops);

函数声明:semid是信号灯集ID,sops指向数组的每一个sembuf结构都刻画一个在特定信号灯上的操作。nsops为sops可数组的大小。 sembuf结构为

struct sembuf

{

  unsigned short sem_num;

short sem_op;

short sem_flg;

}

返回值:成功返回0.否则返回-1

③ semctl 函数

函数定义:int semctl(int semid, int semnum, int cmd, union semun);

函数声明:该系统调用实现对信号灯的各种控制操作,参数semid指定信号灯集;参数cmd指定具体的操作类型参数semnum指定对哪个信号灯操作,只对几个特殊的cmd操作有意义arg用于设置或返回信号灯信息该系统调用详细信息请参见其手册页,这里只给出参数cmd所能指定的操作

IPC_STAT:获取信号灯信息,信息由arg.buf返回

●IPC_SET:设置信号灯信息,待设置信息保存在arg.buf中(manpage给出了可以设置哪些信息)

●GETALL:返回所有信号灯的值,结果保存在arg.array中,参数sennum被忽略

●GETNCNT:返回等待semnum所代表信号灯的值增加的进程数,相当于目前有多少进程在等待semnum代表的信号灯所代表的共享资源

●GETPID:返回最后对 semnum所代表信号灯执行 semop 操作的进程ID

●GETVAL:返回 semnan 所代表信号灯的值

●GETZCNT:返回等待 semnan 所代表信号灯的值变成0的进程数 ●SETALL:通过arg.aray更新所有信号灯的值;同时,更新与本信号集相关的semid_ds结构的sem_ctime成员

●SETVAL:设置 semnum所代表信号灯的值为arg.val

返回值: 调用失败返回-1,成功返回与cmd相关

●Cmd:return value

●GETNCNT:Semncnt

●GETPID:Semp

●GETVAL:Serval

●GETZCNT:Semant

9、 系统 V 共享内存的原理:

进程间需要共享的数据被放在一个叫作IPC共享内存区域的地方,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去。系统V共享内存通过shmget获得或创建一个IPC共享内存区域,并返回相应的标识符。内核在保证shmget获得或创建个共享内存区,初始化该共享内存区相应的Ishmikernel结构注同时,还将在特殊文件系统hm,创建并打开一个同名文件,并在内存中建立起该文件的相应dentryinode结构新打开的文件不属于任何一个进程(任何进程都可以访问该共享内存区)。所有这一切都是通过系统调用shmget完成的。注:每一个共享内存区都有一个控制结构Jstructshmikernel,shmikernel是共享内存区域中非常重要的一个数据结构,它是存储管理和文件系统结合起来的桥梁。

10、信号灯的API

(1)semget函数用于配置信号灯;

(2)semop函数用于信号灯处理;

(3)semctl函数用于控制信号灯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值