共享内存

概要

共享的内存段是用户内存的一部分。每一个进程都有一个指向此内存段的指针。依靠访问权限的设置,所有进程都可以读取这一块空间中的数据。因此进程间的资源是共享的,而不是复制来复制去的。共享内存段对于进程而言,就类似于共享变量对于线程一样。

API

函数原型

int shmget(key_t key, size_t size, int shmflg);

头文件

#include<sys/ipc.h>

#include<sys/shm.h>

描述

创建共享内存段。如果该内存段存在,函数找到它的位置。如果不存在,则创建此共享内存段。

参数说明

key标识共享内存的键值: 0/IPC_PRIVATE。 当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存;如果key的取值为0,而参数shmflg中设置了IPC_PRIVATE这个标志,则同样将创建一块新的共享内存。 

size(单位byte)是要建立共享内存的长度。所有的内存分配操作都是以页为单位的。所以如果一段进程只申请一块只有一个字节的内存,内存也会分配整整一页(i386机器中一页的缺省大小PACE_SIZE=4096字节)这样,新创建的共享内存的大小实际上是从size这个参数调整而来的页面大小。即如果size14096,则实际申请到的共享内存大小为4K(一页)40978192,则实际申请到的共享内存大小为8K(两页),依此类推。

shmflg主要和一些标志有关。其中有效的包括IPC_CREATIPC_EXCL,它们的功能与open()O_CREATO_EXCL相当。 IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则打开操作。 IPC_EXCL 只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。 如果单独使用IPC_CREATshmget()函数要么返回一个已经存在的共享内存的操作符,要么返回一个新建的共享内存的标识符。如果将IPC_CREATIPC_EXCL标志一起使用,shmget()将返回一个新建的共享内存的标识符;如果该共享内存已存在,则返回-1IPC_EXEL标志本身并没有太大的意义,但是和IPC_CREAT标志一起使用可以用来保证所得的对象是新建的,而不是打开已有的对象。

返回值

成功返回共享内存的标识符;不成功返回-1errno储存错误原因。

EINVAL 参数size小于SHMMIN或大于SHMMAX

EEXIST 预建立key所致的共享内存,但已经存在。

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

ENOSPC 超过了系统允许建立的共享内存的最大值(SHMALL )

ENOENT 参数key所指的共享内存不存在,参数shmflg也未设IPC_CREAT位。

EACCES 没有权限。

ENOMEM 核心内存不足。

 

函数原型

 void *shmat( int shmid , char *shmaddr , int shmflag );

头文件

#include<sys/ipc.h>

#include<sys/shm.h>

描述

在进程的地址空间中创建共享内存段的部分

参数说明

shmid是那块共享内存的ID

shmaddr是共享内存的起始地址,NULL

是本进程对该内存的操作模式。如果是SHM_RDONLY(1)的话,就是只读模式。其它的是读写模式

返回值

成功时,这个函数返回共享内存的起始地址。失败时返回-1

 

函数原型

int shmdt( char *shmaddr );

头文件

#include<sys/ipc.h>

#include<sys/shm.h>

描述

将共享内存与当前进程分离。分离共享内存并不会删除他;他只是使得内存对于当前进程不可用。

参数说明

shmat获得的地址

返回值

成功时,返回0。失败时返回-1

 

函数原型

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

头文件

#include<sys/ipc.h>

#include<sys/shm.h>

描述

删除开辟的共享内存。如果不删除的话,那块内存将一直存在。

参数说明

shmid:是共享内存的ID

cmd: 是控制命令,可取值如下:

IPC_STAT 得到共享内存的状态,

IPC_SET 改变共享内存的状态

IPC_RMID 删除共享内存

struct shmid_ds *buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定。

与参数二配套使用,一般设置为NULL

返回值

成功时,返回0。失败时返回-1

 

命令行查看

取得ipc信息:

      ipcs [-m|-q|-s]

-m 输出有关共享内存(shared memory)的信息

-q 输出有关信息队列(message queue)的信息

-s 输出有关遮断器”(semaphore)的信息

%ipcs –m

 

删除ipc

ipcrm -m|-q|-s shm_id

%ipcrm -m 105

 

Sample

使用共享内存的C/S

S:获取当前用户输入,并存放至SM

C:访问SM,取得用户输入

 

server.c

// the server get a string from the stdio, and put it into the shared memory

 

#include <stdio.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <string.h>

 

#define SM_KEY 8888                                  // the key of the shared memory

#define SM_SIZE 1024                                 // size of the shared memory

#define oops(m) {perror(m); exit(1);}                   // exception handling

 

int main()

{

       int sm_id;

       char *mem_ptr;

       int iTemp;

       // create the shared memory if not exist, and get the sm_id of this shared memory

       sm_id = shmget(SM_KEY, SM_SIZE, IPC_CREAT|0777);

       if(sm_id == -1)

              oops("shmget");

       // attach to it and get a pointer to this memory

       mem_ptr = shmat(sm_id, NULL, 0);              // read and write

       if(mem_ptr == NULL)

              oops("shmat");

       // input sth

       bzero(mem_ptr, 1024);

       printf("---------------------------------------------------------------------->/n");

       printf("Input a string whose size is less than 1024:/n");

       gets(mem_ptr);

       // remove the shared memory

       printf("Press any key to remove the shared memory!/n");

       iTemp = getchar();

       iTemp = shmctl(sm_id, IPC_RMID, NULL);

       if(iTemp == -1)

              oops("shmctl");

       return 0;

}

 

client.c

// the client get the string in the shared memory which is put by the server

 

#include <stdio.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <string.h>

 

#define SM_KEY 8888                                  // the key of the shared memory

#define SM_SIZE 1024                                 // size of the shared memory

#define oops(m) {perror(m); exit(1);}                   // exception handling

 

int main()

{

       int sm_id;

       char *mem_ptr;

       int iTemp;

       // create the shared memory if not exist, and get the sm_id of this shared memory

       sm_id = shmget(SM_KEY, SM_SIZE, 0777);

       if(sm_id == -1)

       {

              printf("No shared memory to use, please run server first!/n");

              oops("shmget");

       }

       // attach to it and get a pointer to this memory

       mem_ptr = shmat(sm_id, NULL, 0);              // read and write

       if(mem_ptr == NULL)

              oops("shmat");

       while(strlen(mem_ptr) == 0)

       {

              printf("Please wait for the server put sth in the shared memory first/n");

              sleep(1);

       }

       // get the string

       printf("---------------------------------------------------------------------->/n");

       printf("The string in the shared memory which is put by the server is: %s/n", mem_ptr);

       return 0;

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值