XSI IPC 通讯之同享存储ITeye - 凯发娱乐

XSI IPC 通讯之同享存储ITeye

2019年03月28日10时09分38秒 | 作者: 潇晗 | 标签: 存储,同享,回来 | 浏览: 2649

  在和两节中,咱们评论了音讯行列和信号量,这一节将持续评论同归于 XSI IPC 的存储同享。
  同享存储答应多个进程同享一个给定的存储区。由于数据不需要在进程之间仿制,所以这是一种较快的 IPC。要注意的是,当一个进程在修正同享存储区时,其他进程不该该去操作这块区域。一般运用信号量来同步同享存储拜访(当然也可运用记载锁或互斥量)。
  mmap 便是同享存储的一种方法,它是将同一个文件映射到各个进程的地址空间。XSI 同享存储和内存映射的文件的区别是,前者没有相关的文件。XSI 同享存储段是内存的匿名段。
  下表给出了影响同享存储的体系约束。

  内核为每个同享存储段维护着一个结构,它至少包括下面这些成员。
struct shmid_ds{
 struct ipc_perm shm_perm;
 size_t shm_segsz; // size of segment in bytes
 pid_t shm_lpid; // pid of last shmop()
 pid_t shm_cpid; // pid of creator
 shmatt_t shm_nattch; // number of current attaches
 time_t shm_atime; // last-attach time
 time_t shm_dtime; // last-detach time
 time_t shm_ctime; // last-change time
 /* ... */

  其间的 ipc_perm 结构见。shmatt_t 类型界说为无符号整型,它至少与 unsigned short 相同大。
  shmget 函数能够创立或取得一个同享存储标识符。shmctl 函数可对同享存储段履行多种操作。shmat 函数可将创立好的同享存储段衔接到进程的地址空间中。shmdt 函数可将同享段与进程别离。
#include sys/shm.h 
int shmget(key_t key, size_t size, int flag);
 /* 回来值:若成功,回来同享存储 ID;不然,回来 -1 */
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
 /* 回来值:若成功,回来 0;不然,回来 -1 */
void *shmat(int shmid, const void *addr, int flag);
 /* 回来值:若成功,回来指向同享存储段的指针;不然,回来 -1 */
int shmdt(const void *addr);
 /* 回来值:若成功,回来 0;不然,回来 -1 */

  shmget 函数在创立一个新段时,会初始化 shmid_ds 结构的下列成员。
  * ipc_perm 结构按一节中的所述进行初始化。该结构中的 mode 按 flag 中的相应权限位设置。
  * shm_lpid、shm_nattach、shm_atime 和 shm_dtime 都设置为 0。
  * shm_ctime 设置为当时时刻。
  * shm_segsz 设置为恳求的 size。
  参数 size 是同享存储段的长度,以字节为单位,一般将其向上取为体系页长的整数倍。若运用指定的 size 值并非体系页长的整倍数,则最终一页的余下部分是不行运用的。假如是在引证一个现存的段,则可将 size 指定为 0。创立一个新段时,段内的内容会被初始化为 0。
  shmctl 函数的 cmd 参数可指定下列 5 种指令中的一种,使其在 shmid 指定的段上履行。
  * IPC_STAT:取此段的 shmid_ds 结构,并将其寄存在 buf 指向的结构中。
  * IPC_SET:将字段 shm_perm.uid、shm_perm.gid、shm_perm.mode 从 buf 指向的结构仿制到此行列相关的 shmid_ds 结构中。此指令只能由下列两种进程履行:一种是其有用用户 ID 等于 shm_perm.cuid 或 shm_perm.uid,另一种是具有超级用户特权的进程。
  * IPC_RMID:从体系中删去该同享存储段。由于每个同享存储段维护着一个衔接计数(及 shm_nattch字段),所以除非运用该段的最终一个进程停止或与该段别离,不然不会实践上删去该存储段。不过不论此段是否仍在运用,该段标识符都会被当即删去,不能再用 shmat 与该段衔接。该指令也只能由上面提及的两种进程履行。
  Linux 和 Solaris 还供给了如下的别的两种指令。
  * SHM_LOCK:在内存中对同享存储段加锁。只能由超级用户履行。
  * SHM_UNLOCK:解锁同享存储段。也只能由超级用户履行。
  同享存储段衔接到调用进程的哪个地址上与 shmat 函数的 addr 参数以及 flag 中是否指定了 SHM_RND 位有关,有以下几种状况。
  (1)假如 addr 为 0,则此段衔接到由内核挑选的第一个可用地址上(引荐)。
  (2)假如 addr 非 0,而且没有指定 SHM_RND,则此段衔接到 addr 所指定的地址上。
  (3)假如 addr 非 0,而且指定了 SHM_RND,则此段衔接到(addr - (addr mod SHMLBA))所表明的地址上。SHM_RND 指令的意思是“取整”,SHMLBA 的意思是“低鸿沟地址倍数”,它总是 2 的乘方,该算式是将地址向下取最近 1 个 SHMLBA 的倍数。
  假如在 flag 中指定了 SHM_RDONLY 位,则以只读方法衔接此段,不然以读写方法衔接。
  shmat 的回来值是该段所衔接的实践地址,假如犯错则回来 -1。假如 shmat 成功履行,那么内核将使相应 shmid_ds 结构中的 shm_nattch 计数器值加一。
  当对同享存储段的操作现已结束时,就可调用 shmdt 函数与该段别离。不过这并不从体系中删去其标识符以及相关的数据结构,该标识符依然存在,直至某个进程调用带 IPC_RMID 指令的 shmctl 函数来特别删去它停止。其间的 addr 参数是之前调用 shmat 时的回来值。假如成功,shmdt 将使相关 shmid_ds 结构中的 shm_nattch 计数器减一。
  下面这个实例演示了将 addr 参数设为 0 的 shmat 函数的用法,它打印了一些特定体系寄存各种类型的数据的方位信息(这些信息的阐明见一节)。
#include stdio.h 
#include stdlib.h 
#include sys/shm.h 
#define ARRAY_SIZE 40000
#define MALLOC_SIZE 100000
#define SHM_SIZE 100000
#define SHM_MODE 0600 // user read/write
char array[ARRAY_SIZE]; // uninitialized data = bss
int main(void){
 int shmid;
 char *ptr, *shmptr;
 printf("array[] from %p to %p\n", array[0], array[ARRAY_SIZE]);
 printf("stack around %p\n", shmid);
 if((ptr=malloc(MALLOC_SIZE))  NULL){
 printf("malloc error\n");
 exit(1);
 printf("malloced from %p to %p\n", ptr, ptr+MALLOC_SIZE);
 shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE);
 if((shmptr=shmat(shmid, 0, 0)) != (void *)-1){
 printf("shared memory attached from %p to %p\n", shmptr, shmptr+SHM_SIZE);
 shmctl(shmid, IPC_RMID, 0);
 exit(0);

  在一个根据 Intel 的 64 位 Linux 体系上运转此程序的成果如下:
$ ./prtMemoryLayout.out
array[] from 0x6020c0 to 0x60bd00
stack around 0x7fff957b146c
malloced from 0x9e3010 to 0x9fb6b0
shared memory attached from 0x7fba578ab000 to 0x7fba578c36a0

  下图显现了这种存储区布局示意图。

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表凯发娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1

    XSI IPC 通讯之同享存储ITeye

    存储,同享,回来
  • 2
  • 3
  • 4

    vi编辑器中文乱码ITeye

    文件,编码,体系
  • 5
  • 6

    处理apiITeye

    运转,下载,装置
  • 7

    (转)MAC JDK版别切换ITeye

    版别,装置,对应
  • 8
  • 9

    Linux入门学习笔记ITeye

    文件,光标,用户
  • 10