共享内存是三个IPC机制中的一个,它是两个或多个进程进行通信的一种非常有效的方式。 共享内存的实现,主要是在内核中找一段内存作为共享内存,这个共享内存通过映射的方法可以被其他进程所共同使用。当一个进程改变了共享内存的内容的时候,其他进程也会感知到这块内存中的内容发生了改变。因为数据不需要在C/S端复制,然后再把数据写到每个进程的物理内存,消除了多次拷贝带来的性能和时间的损耗,所以这也是最快的一种IPC。

共享内存的生命周期由内核决定,即由内核中申请共享内存,释放也是由内核执行的动作,其余进程和共享内存之间只是映射关系,即使进程被挂起或者kill掉,只要内核不发起释放内存的动作,他就是一直存在的,也是可以一直被访问的。

共享内存并未提供同步机制,一种是多个进程对内存同一个地址写时存在问题,另一种是一个进程在写,同时另一个进程在读。想要达到多个进程对共享内存的同步访问,还需要信号量来进行控制。

共享内存中运用到的函数


1、shmget

int shmget(key\_t key, size\_t size, int shmflg);

[参数key]:由ftok生成的key标识,标识系统的唯一IPC资源。

[参数size]:需要申请共享内存的大小。在操作系统中,申请内存的最小单位为页,一页是4k字节,为了避免内存碎片,我们一般申请的内存大小为页的整数倍。

[参数shmflg]:如果要创建新的共享内存,需要使用IPC\_CREAT,IPC\_EXCL,如果是已经存在的,可以使用IPC\_CREAT或直接传0。 通常是IPC\_CREAT | IPC\_EXCL | 0666

[返回值]:成功时返回一个新建或已经存在的的共享内存标识符,取决于shmflg的参数。失败返回-1并设置错误码。

用法:通过ftok函数可以生成唯一的key标识,唯一的key标志通过shmget函数生成size大小的共享内存,函数的返回值是shmID,一个唯一的key对应唯一的shmID。

其他进程想要和生成的这段共享内存映射的时候就需要这个shmID,可以通过shmget(key,0,0)进行生成

2、shmat ( ):挂接共享内存(attach)

void *shmat(int shmid, const void *shmaddr, int shmflg);

[参数shmid]:共享存储段的标识符。

[参数*shmaddr]:shmaddr = 0,则存储段连接到由内核选择的第一个可以地址上(推荐使用)。

[参数shmflg]:若指定了SHM\_RDONLY位,则以只读方式连接此段,否则以读写方式连接此段。

[返回值]:成功返回共享存储段的指针(虚拟地址),并且内核将使其与该共享存储段相关的shmid\_ds结构中的shm\_nattch计数器加1(类似于引用计数);出错返回-13、

3、shmdt ( ):去关联共享内存(datach)

int shmdt(const void *shmaddr);

[参数*shmaddr]:连接以后返回的地址。

[返回值]:成功返回0,并将shmid\_ds结构体中的 shm\_nattch计数器减1;出错返回-1

4、shmctl ( ):销毁共享内存

int shmctl(int shmid, int cmd, struct shmid\_ds *buf);

[参数shmid]:共享存储段标识符。

[参数cmd]:指定的执行操作,设置为IPC\_RMID时表示可以删除共享内存。

[参数*buf]:设置为NULL即可。

[返回值]:成功返回0,失败返回-1。

linux中的共享内存管理指令(可视化共享内存的情况)

1、显示所有的IPC设施

# ipcs -a

2、显示所有的消息队列Message Queue

# ipcs -q

3、显示所有的信号量

# ipcs -s

4、显示所有的共享内存

# ipcs -m

5、显示IPC设施的详细信息

# ipcs -q -i id  

id 对应shmid、semid、msgid等。-q对应设施的类型(队列),查看信号量详细情况使用-s,查看共享内存使用-m。

6、删除共享内存IPC

ipcrm -m| -q| -s shm_id

标签: 进程, int, 共享内存, IPC, key, 通信, shmid, 当中

相关文章推荐

添加新评论,含*的栏目为必填