`
microjava
  • 浏览: 309444 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

c语言编程基础之IPC共享内存

阅读更多
共享内存(Shared Memory)是最简单的进程间通信方式,它允许多个进程访问相同的内存,一个进程改变其中的数据后,其他的进程都可以看到数据的变化。

共享内存是进程间最快速的通信方式:
`进程共享同一块内存空间。
`访问共享内存和访问私有内存一样快。
`不需要系统调用和内核入口。
`不造成不必要的内存复制。

内核不对共享内存的访问进行同步,因此程序员必须自己提供同步。

使用共享内存:
`某个进程分配内存段。
`使用这个内存段的进程要连接(attach)这个内存段。
`每个进程使用完共享内存段后,要分离(detach)这个内存段。
`在某个地方,必须有一个进程来销毁这个内存段。

Linux的内存模型:
`每个进程的虚拟内存被分为页(page)。
`每个进程维护自己的内存地址到虚拟内存页之间的映射。
`实际的数据存在于进程的内存地址上。
`尽管每个进程有自己的地址空间,多个进程的映射还是可以指向相同的页。

所有的共享内存段的大小,都是Linux内存页大小的整数倍。
Linux的页大小是4KB,不过程序员应该使用getpagesize函数来获得这个值。

分配:shmget
`第一个参数是一个整型的键,用于指定要创建的段。无关的进程可以通过指定同一个键来访问同一段共享内存。
`使用常量IPC_PRIVATE作为第一个参数,可以避免键的冲突。
`第二个参数是分配的段的大小(字节数)。实际分配的字节数会舍弃多余部分到页大小的整数倍。
`第三个参数是位标志,用来表示创建的选项。
``IPC_CREATE:表明要创建新的共享内存空间。
``IPC_EXCL:总是和上一个标志一起使用。如果指定键的共享内存段已经存在,这个标志会导致调用失败;如果没有指定这个标志,调用会返回已经占用这个键的共享内存段。
``模式标志:9个bit的标志,和系统的文件权限使用相同的标志,不过执行标志无效。这些标志定义在<sys/stat.h>中。
`返回值是新创建的或者取得的内存段的标志符(SHMID)。

连接:shmat
`第一个参数是由shmget得到的标志符(SHMID)。
`第二个参数是指向你想要映射到的本进程的地址空间的指针。如果指定NULL,Linux负责选择一个可用的地址。

/*共享内存  打印各种不同类型的数据所存放的位置   */
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 4000
#define MALLOC_SIZE 10000
#define SHM_SIZE 10000
#define SHM_MODE 0666  //设置读写权限

char array[ARRAY_SIZE];

main()
{
  int shmid;
  char *p,*shmp;

  printf("array[] from %lx to %ls \n",(unsigned long)&array[0],(unsigned long)&array[ARRAY_SIZE] );
  printf("stack around %lx \n",(unsigned long)&shmid);

  if ((p = malloc(MALLOC_SIZE)) == NULL)
     printf("malloc error! errno=%d\n",errno);
  printf("malloced from %lx to %lx\n",(unsigned long)p,(unsigned long)p+MALLOC_SIZE);
  
  if((shmid= shmget(IPC_PRIVATE,SHM_SIZE,SHM_MODE)) < 0){
       if((shmid =  shmget(IPC_PRIVATE,SHM_SIZE,IPC_CREAT|SHM_MODE)) < 0)
          printf("creat shmget error! error=%d\n",errno);
          exit(-1);
  }

  /*if((shmid = shmget(IPC_PRIVATE,SHM_SIZE,IPC_CREAT|SHM_MODE)) < 0)
     printf("shmget error! errno=%d \n",errno);*/ 
  if((shmp = shmat(shmid,0,0)) == (void*) -1)
     printf("shmat error! errno=%d\n",errno);
  printf("shared memory attached from %lx to %lx\n",(unsigned long)shmp,(unsigned long)shmp+SHM_SIZE);
  
  if(shmctl(shmid,IPC_RMID,0) < 0)
     printf("shmctl error! errno=%d\n",errno);
  
  shmdt(shmp);
  exit(0);
}


分享到:
评论

相关推荐

    宋劲彬的嵌入式C语言一站式编程

    1. 程序和编程语言 2. 自然语言和形式语言 3. 程序的调试 4. 第一个程序 2. 常量、变量和表达式 1. 继续Hello World 2. 常量 3. 变量 4. 赋值 5. 表达式 6. 字符类型与字符编码 3. 简单函数 1. 数学函数 2. 自定义...

    linux编程白皮书

    对内存管理、进程及其通信机制、PCI、内核模块编程及内核系统结构作了详细的解释,且附有很多程序代码实例。对深入研究Linux下的编程有很大的帮助。 目 录 雷蒙序 简介 Linux文档工程小组“公告” 译者序 第一部分...

    Linux编程资料

    2.1.3 共享虚拟内存 18 2.1.4 物理寻址模式和虚拟寻址模式 18 2.1.5 访问控制 18 2.2 高速缓存 19 2.3 Linux页表 20 2.4 页分配和回收 21 2.4.1 页分配 22 2.4.2 页回收 22 2.5 内存映射 22 2.6 请求调页 23 2.7 ...

    Linux编程从入门到精通

    2.1.3 共享虚拟内存 18 2.1.4 物理寻址模式和虚拟寻址模式 18 2.1.5 访问控制 18 2.2 高速缓存 19 2.3 Linux页表 20 2.4 页分配和回收 21 2.4.1 页分配 22 2.4.2 页回收 22 2.5 内存映射 22 2.6 请求调页 23 2.7 ...

    LINUX编程白皮书

    对内存管理、进程及其通信机制、PCI、内核模块编程及内核系统结构作了详细的解释,且附有很多程序代码实例。对深入研究Linux下的编程有很大的帮助。 目 录 雷蒙序 简介 Linux文档工程小组“公告” 译者序 第一部分 ...

    Linux编程白皮书

    2.1.3 共享虚拟内存 18 2.1.4 物理寻址模式和虚拟寻址模式 18 2.1.5 访问控制 18 2.2 高速缓存 19 2.3 Linux页表 20 2.4 页分配和回收 21 2.4.1 页分配 22 2.4.2 页回收 22 2.5 内存映射 22 2.6 请求调页 23 2.7 ...

    LINUX编程白皮书 (全集)

    2.1.3 共享虚拟内存 18 2.1.4 物理寻址模式和虚拟寻址模式 18 2.1.5 访问控制 18 2.2 高速缓存 19 2.3 Linux页表 20 2.4 页分配和回收 21 2.4.1 页分配 22 2.4.2 页回收 22 2.5 内存映射 22 2.6 请求调页 23 2.7 ...

    UNIX高级编程 计算机科学丛书

    13.3 编程规则 13.4 出错记录 13.4.1 SVR4流log驱动程序 13.4.2 4.3+BSD syslog设施 13.5 客户机-服务器模型 13.6 小结 习题 第14章 进程间通信 14.1 引言 14.2 管道 14.3 popen和 pclose函数 14.4 协同进程 14.5 ...

    操作系统实验

    5、进程间通信(IPC):共享内存机制 (1) 共享存储区的创建,附接和断接 使用系统调用shmget(),shmat(),msgdt(),shmctl(),编制一长度为1K的消息发送和接收的程序。 1)为了便于操作和观察结果,用一个程序作为...

    RED HAT LINUX 6大全

    第四部分为Linux编程;第五部分为附录。本书内容翔实、涉及领域广泛,并且提供了详细的例子和大量的参考资料(包括书籍、电子文档和Internet站点),是一本学习、使用和管理Linux不可多得的好书。 目 录 译者序 前言...

Global site tag (gtag.js) - Google Analytics