共享内存和操作共享内存几个函数的用法

简介:共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同
malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。

在创建共享内存和操作共享内存的时候被下面这些函数的参数弄糊涂了,

遂写下各个函数的说明。

所需头文件

#include<sys/ipc.h>

#include<sys/shm.h>

函数

(1)shmget(key_t key,int size,int shmflag)

函数说明

shmget()用来取得参数key所关联的共享内存识别代号,如果key是IPC_PRIVATE则会建立新的共享内存,

其大小由size决定,如果key不为IPC_PRIVATE,也不是已建立的IPC key,那么系统回视参数

shmflag是否有IPC_CREAT位,来确定以IPC key为参数的key的

共享内存。如果参数shmflag包含了IPC_CRATE 和IPC_EXCL位,

而无法依参数key来建立共享内存,则表示该共享内存已存在。

错误代码:

EINVAL  参数size小于SHMMIN或大于SHMMAX

EEXIST   欲建立key所致新的共享内存,但已存在

EIDRM    参数key所致的共享内存已删除

ENOENT   参数key所指的共享内存不存在,参数shmflag也没设置         IPC_CREAT位

ENOMEM  核心内存不足

ENOSPC   已超过系统允许可建立的共享内存最大值

(2)int shmdt(const void *shmaddr)

函数说明:

shmdt()用来将先前用shmat()连接好的共享内存脱离目前的进程,

参数shmaddr为先前shmat()返回的共享内存地址

(3)int shmctl(int shmid,int cmd,struct shmid_ds *buf)

shmctl()提供了几种方式来控制共享内存操作,其中cmd有下列几种数值:

IPC_STAT 把共享内存的shmid_ds结构数据复制到引数buf

IPC_SET  将参数buf所指的shmid_ds结构中的shm_perm.uid、shm_perm.gid

shm_perm.mode复制到共享内存的shmid_ds结构中

IPC_RMID 删除共享内存和其数据结构

SHM_LOCK  不让此共享内存置换到swap

SHM_UNLOCK  允许此共享内存置换到swap

SHM_LOCK 和SHM_UNLOCK为linux特有,且唯有超级用户允许使用

shmid_ds 的结构定义如下

struct shmid_ds

{

struct ipc_perm  shm_perm;

int     shm_segsz;//共享内存大小,以字节计算

time_t  shm_atime;//最后一次attach此共享内存的时间

time_t  shm_dtime;//最后一次detach此共享内存的时间

time_t  shm_ctime;//最后一次更改此共享内存的时间

unsigned short shm_cpid;//建立此共享内存的进程识别码

unsigned short shm_lpid;//最后一次操作此共享内存的进程识别码

short shm_nattch;

unsigned short shm_npages;

unsigned long *shm_pages;

struct shm_desc *attaches;

};

注意(1)要理解各个函数参数有哪些

(2)这些参数的作用是什么

(3)这些会帮助理解函数的使用方法(工作机理)

创建共享内存和操作共享内存实例

#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<string.h>
 #define KEY  1234
 #define SIZE 1024

int main()
{

 int shmid;
 char *shmaddr;
 struct shmid_ds buf;
//建立共享内存
 shmid = shmget(KEY,SIZE,IPC_CREAT | 0600);

  if( fork() == 0 )
    {
     shmaddr =(char *)shmat(shmid,NULL,0);
      strcpy(shmaddr,"hi! i am child process!\n");
      shmdt(shmaddr);
      return 0;
    }
  else
    {
     sleep(3);
     shmctl(shmid,IPC_STAT,&buf);
      printf("shm_segsz = %d bytes\n",buf.shm_segsz);
  printf("shm_cpid = %d\n",buf.shm_cpid);
  printf("shm_lpid = %d\n",buf.shm_lpid);
  shmaddr =(char *)shmat(shmid,NULL,0);
  printf("%s",shmaddr);
  shmdt(shmaddr);
   shmctl(shmid,IPC_RMID,NULL);
    }
 return 0;
}
时间: 2024-10-19 21:51:45

共享内存和操作共享内存几个函数的用法的相关文章

22内存文件操作

前面介绍了基本文件操作.数据流文件操作和文本文件操作.本次简单介绍内存文件操作.内存文件本质就是建立一块公共内存区域,可以往里读.写. 下面我们使用一段代码来看看QBuffer的有关操作: QBuffer memFile();               //内存文件对象 //打开 bool bIsOk=memFile.open(QIODevice::WriteOnly); if(bIsOk==true) { memFile.write("1111111111"); memFile.w

Android 性能优化之内存泄漏检测以及内存优化(上)

在 Java 中,内存的分配是由程序完成的,而内存的释放则是由 Garbage Collecation(GC) 完成的,Java/Android 程序员不用像 C/C++ 程序员一样手动调用相关函数来管理内存的分配和释放,虽然方便了很多,但是这也就造成了内存泄漏的可能性,所以记录一下针对 Android 应用的内存泄漏的检测,处理和优化的相关内容,上篇主要会分析 Java/Android 的内存分配以及 GC 的详细分析,中篇会阐述 Android 内存泄漏的检测和内存泄漏的常见产生情景,下篇会

clients(PV操作共享内核内存进行输入输出分屏) - server(进程间通信)模型实现

1.拓扑结构 2.PV操作共享内核内存进行输入输出分屏 (1) 1 int semop(int semid,struct sembuf *sops,size_t nsops): 功能描述 操作一个或一组信号. semid: 信号集的识别码,可通过semget获取. sops: 指向存储信号操作结构的数组指针,信号操作结构的原型如下 1 struct sembuf 2 { 3 unsigned short sem_num; /* semaphore number */ 4 short sem_op

VC++ 共享内存读写操作

此解决方案含两个工程文件,一个是写操作工程文件,即把任意字符串写入创建的共享内存里,另外一个读操作工程文件,则是读取共享内存里的数据,从而实现了进程之间的共享内存读写操作. 源码下载

inux内存映射和共享内存理解和区别

可以看到内存映射中需要的一个参数是int fd(文件的标识符),可见函数是通过fd将文件内容映射到一个内存空间, 我需要创建另一个映射来得到文件内容并统计或修改,这时我创建这另一个映射用的仍是mmap函数, 它仍需要用到fd这个文件标识,那我不等于又重新打开文件读取文件里的数据 1.既然这样那同对文件的直接操作有什么区别呢? 2.映射到内存后通过映射的指针addr来修改内容的话是修改共享内存里的内容还是文件的内容呢? 3.解决上面2个问题,我还是想确切知道共享内存有什么用??? 一种回答|: 1

redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换

原文:redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换 一.  概述 对于前面的五章中,已清楚了数据对象的类型以及命令实现,其实还有一种数据对象为HyperLogLog,以后需要用到再了解.下面再了解类型检查,内存回收,对象共享,对象的空转时长. 1.1   类型检查与命令多态 redis中用于操作键的命令基本上可以分为两种类型,一种是可以对任何的键执行,如:del, expire,rename,type,object 这些命令等,对于这些命令属于多态命令.另一种命令

数组逆序=全局内存版 VS 共享内存版

全局内存版 1 #include <stdio.h> 2 #include <assert.h> 3 #include "cuda.h" 4 #include "cuda_runtime.h" 5 #include "device_launch_parameters.h" 6 //检查CUDA运行时是否有错误 7 void checkCUDAError(const char* msg); 8 // Part3: 在全局内存

浅谈操作系统对内存的管理

转自http://www.cnblogs.com/CareySon/archive/2012/04/25/2470063.html 简介 内存是计算机中最重要的资源之一,通常情况下,物理内存无法容纳下所有的进程.虽然物理内存的增长现在达到了N个GB,但比物理内存增长还快的是程序,所以无论物理内存如何增长,都赶不上程序增长的速度,所以操作系统如何有效的管理内存便显得尤为重要.本文讲述操作系统对于内存的管理的过去和现在,以及一些页替换的算法的介绍. 对于进程的简单介绍 在开始之前,首先从操作系统的角

【内存类操作】浅谈内存拷贝异常

结合本人在实际项目中所积累的经验,以及曾经犯过的错误,堆内存操作类函数做一个简单的剖析,抛砖引玉,欢迎大家吐槽. 首先,讲一下内存使用异常发生的几种场景. 1.野指针的使用,使用已经释放的指针,如果向野指针中写内容,就极有可能导致设备重启或任务挂死.因为,正在运行的任务的地址被意外的改写. [避免策略]函数入参要判空,指针使用(包括释放)之前一定要释放. 2.内存函数的错误使用: void *memset(void *s, int ch, size_t n); c语言中在<memory.h>或