多进程与多线程(四)

1.1.2.1 共享内存

所谓共享内存,就如同两个地下工作者,送情报的把写有字的小纸条放在大树下,取情报的拿走小纸条,这就实现了单方面联络通信;如果取情报的拿走小纸条的时候再附上一个小纸条写上“收到勿念”,在下次送情报的来时取走,就实现了所谓的“双工”通信;在计算机领域,只不过这个存放小纸条的大树长的模样和大树有些许的不同。我们通过Linux的相关函数来认识一下这个过程。

首先,共享内存块是个内存区域,这样才能供小纸条存放。

其次,只有多个进程存在且需要交流时才有创建的必要(如Linux下提供shmget函数,通过指定第三个参数为“IPC_CRESTE | IPC_EXCL”这样的方式,创建共享内存块)。

第三,既然要送小纸条、取小纸条,就需要知道小纸条的存在,所以共享内存要有一个名字以做标识,这样根据标识名称,多个进程间才能操作这样的区域(如Linux系统的shmget函数的第一个参数“key”就是这样的一个名称标识)。

第四,共享内存总是需要创建的,被创建的“共享内存块”应该存在于创建者的进程空间中(注意,进程的空间是独立于其他进程的,自己的领地不能容忍他人侵犯),可其他进程偏偏要操作共享内存块,可见这块内存一定特殊于进程通过malloc等函数申请的内存空间,实际上这块空间的真正拥有者是操作系统,而创建共享内存的的进程无非只是个管理者或使用者,其拥有的,只是操作系统管理的一段空间的访问权。所以,需要自己和其他进程能够把共享的内存块划分到自己的*范围内,这就是Linux系统通过shmat函数,将共享内存映射到自己的内存空间。

第五,在把共享内存块映射到自己的地址空间管辖范围内,就可以控制共享内存块。控制可以分为两大种方式,一是通过shmctl函数获得共享内存的信息、设定共享内存的信息或者删除共享内存。当然,删除操作可以由进程发出,也可以交由操作系统完成。另外一种控制方式就是把进程自己同共享内存挂钩(shmat函数,将共享内存映射到自己的内存空间)与脱钩(shmdt函数,将自己与共享内存的联系断开)。

第六,控制共享内存实际上不是我们的主要目的,读写信息才更为重要。那么,如何读写呢?注意,通过shmat函数映射得到的、是shmat函数的返回值对应的共享内存的地址(char *)。读写此地址块,非常简单。


多进程与多线程(四)