共享内存(Shared Memory)介绍

来源:互联网 发布:自学linux 好找工作吗 编辑:程序博客网 时间:2024/06/05 14:16

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


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

(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 674int 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);} elseprintf("shmctl() call failed.\n");// 共享内存区段的脱离ret = shmdt(mem);if (ret == 0)printf("Successfully detach memory.\n");elseprintf("Memory detached failed %d\n", errno);// 删除该共享内存区ret = shmctl(shareMemoryId, IPC_RMID, 0);if (ret == 0)printf("Share memory removed.\n");elseprintf("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.


0 0