共享内存(Shared Memory)介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WAN_EXE/article/details/56484664

共享内存是常用的进程间通信,两个进程可以直接共享访问同一块内存区域。


实现共享内存的步骤如下:

(1) 创建内存共享区

进程1通过操作系统提供的api从内存中申请一块共享区域,linux系统中可以通过shmget函数实现,生成的共享内存块与某个特定的key进行绑定。

(2) 映射共享内存到进程1中

在linux环境中,可以通过shmat实现。

(3)映射共享内存到进程2中

进程2通过进程1的shmget函数和同一个key值,然后执行shmat,将这个内存映射到进程2中。

(4)进程1与进程2中相互通信

共享内存实现两个映射后,可以利用该区域进行信息交换,由于没有同步机制,需要参与通信的进程自己协商处理。

(5)撤销内存映射关系

完成通信之后,需要撤销之前的映射操作,通过shmdt函数实现。

(6)删除共享内存区

在linux中通过shctl函数来实现。

以下为举例实现调用linux系统提供的相关函数。

* One shmid data structure for each shared memory segment in the system. */
        struct shmid_ds {
                struct ipc_perm shm_perm;        /* operation perms */
                int     shm_segsz;               /* size of segment (bytes) */
                time_t  shm_atime;               /* last attach time */
                time_t  shm_dtime;               /* last detach time */
                time_t  shm_ctime;               /* last change time */
                unsigned short  shm_cpid;        /* pid of creator */
                unsigned short  shm_lpid;        /* pid of last operator */
                short   shm_nattch;              /* no. of current attaches */

                                                 /* the following are private */

                unsigned short   shm_npages;     /* size of segment (pages) */
                unsigned long   *shm_pages;      /* array of ptrs to frames -> SHMMAX */ 
                struct vm_area_struct *attaches; /* descriptors for attaches */
        };

(1) test1.c

/*
 * 共享内存中几个常见函数呢的使用
 * shmget, shmat, shmdt, shmctl
 */
#include <stdio.h>
#include <unistd.h>	// getpagesize()
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>

#define SHARE_MEMORY_KEY 674
int main() {
	// 获取系统中页面的大小,
	printf("page size = %d\n", getpagesize());

	int shareMemoryId, ret;
	// 创建页面大小的共享内存区段
	shareMemoryId = shmget(SHARE_MEMORY_KEY, getpagesize(), 0666|IPC_CREAT);
	
	if (shareMemoryId > 0)
		printf("Create a shared memory segment %d\n", shareMemoryId);

	// 共享内存区段的挂载
	void* mem;
	mem = shmat(shareMemoryId, (const void *)0, 0);

	// 获取一个内存区段的信息
	struct shmid_ds shmds;
	ret = shmctl(shareMemoryId, IPC_STAT, &shmds);
	if (ret == 0) {
		printf("Size of memory segment is %d bytes.\n", (int) shmds.shm_segsz);
		printf("Number of attach %d\n", (int) shmds.shm_nattch);
	} else
		printf("shmctl() call failed.\n");

	// 共享内存区段的脱离
	ret = shmdt(mem);
	if (ret == 0)
		printf("Successfully detach memory.\n");
	else
		printf("Memory detached failed %d\n", errno);

	// 删除该共享内存区
	ret = shmctl(shareMemoryId, IPC_RMID, 0);
	if (ret == 0)
		printf("Share memory removed.\n");
	else
		printf("Share memory remove failed.\n");

	return 0;
}

输出:
wang@wang:~/test/test6$ ./a.out
page size = 4096
Create a shared memory segment 4751390
Size of memory segment is 4096 bytes.
Number of attach 1
Successfully detach memory.
Share memory removed.


猜你喜欢

转载自blog.csdn.net/WAN_EXE/article/details/56484664