Linux CPOSIX 共享内存使用

人生必须的知识就是引人向光明方面的明灯。这篇文章主要讲述Linux CPOSIX 共享内存使用相关的知识,希望能为你提供帮助。
POSIX 共享内存能够让无关进程共享一个映射区域而无需创建一个相应的映射文件,Linux 内核从 2.4 起开始支持 POSIX 共享内存。Linux 使用挂载于 ??/dev/shm??? 目录下的专用 ??tmpfs?? 文件系统,这个文件系统具有内核持久性——它所包含的共享内存对象会一直持久,即使当前不存在任何进程打开它,但这些对象会在系统关闭后丢失。


共享内存区域占据的内存总量受限于底层的 ??tmpfs??? 文件系统的大小,这个文件系统通常会在启动时使用默认大小进行挂载。如果有必要的话,超级用户能够通过命令 ??mount -o remount,size=< num-bytes> ??重新挂载这个文件系统来修改它的大小。



文章目录
  • ??创建??
  • ??写入??
  • ??读出??
  • ??删除??
  • ??在其它程序中使用工具??
编译步骤,需要链接 ??-lrt???,比如:??sudo gcc pshm_create.c -o pshm_create -lrt??
创建??int shm_open(const char *name, int oflag, mode_t mode); ??
name 参数标识出了待创建或待打开的共享内存对象;oflag 参数是一个改变调用行为的位掩码;mode参数与该内存对象的所有权和组所有权有关,mode参数能取的位值与文件上的权限位值是一样的。
oflag:
  • ??O_CREAT?? 对象不存在时创建对象
  • ??O_EXCL??? 与??O_CREAT??? 互斥地创建对象,如果??O_CREAT?? 也被设置,能够确保调用者是对象的创建者,如果对象已经存在,那么就返回一个错误
  • ??O_RDONLY?? 打开只读访问
  • ??O_RDWR?? 打开读写访问
  • ??O_TRUNC?? 将对象长度截断为 0
如果 oflag 参数中不包含 ??O_CREAT???,那么就打开一个既有对象,如果指定了 ??O_CREAT??,那么就在对象不存在时创建对象。
// POSIX share mem
// sudo gcc pshm_create.c -o pshm_create -lrt

#include < stdio.h>
#include < stdlib.h>
#include < unistd.h>
#include < fcntl.h>
#include < sys/mman.h>
#include < sys/stat.h>
#include < getopt.h>

// int shm_open(const char *name, int oflag, mode_t mode);

static void usageError(const char *progName)

fprintf(stderr, "Usage: %s [-cx] name size [octal-perms]\\n", progName);
fprintf(stderr, "\\t-c Create sharedmemory (O_CREAT)\\n");
fprintf(stderr, "\\t-x Create exclusively (O_EXCL)\\n");
exit(EXIT_FAILURE);


int main(int argc, char *argv[])

int flags, opt, fd;
mode_t perms;
long long int size; // size_t size;
void *addr;

flags = O_RDWR;
while((opt = getopt(argc, argv, "cx")) != -1)

switch(opt)

case c: flags |= O_CREAT; break;
case x: flags |= O_EXCL; break;
default: usageError(argv[0]);


// printf("argc=%d, optind=%d\\n", argc, optind);
if(optind + 1 > = argc)
usageError(argv[0]);
size = atol(argv[optind+1]);
perms = S_IRUSR | S_IWUSR;
// printf("%lld\\n", size);

// create shared memory object and set its size

fd = shm_open(argv[optind], flags, perms);
if(fd == -1)
exit(EXIT_FAILURE);

if(ftruncate(fd, size) == -1)
exit(EXIT_FAILURE);

// map shared memory object

addr = mmap(NULL,size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(addr == MAP_FAILED)
exit(EXIT_FAILURE);

exit(EXIT_SUCCESS);

创建一个长度 1000 字节的共享内存对象,然后在 ??/dev/shm??? 中使用 ??ls??? 命令显出了这个对象。

写入
#include < stdio.h>
#include < stdlib.h>
#include < unistd.h>
#include < fcntl.h>
#include < sys/mman.h>
#include < sys/stat.h>
#include < getopt.h>
#include < string.h>

int main(int argc, char *argv[])

int fd;
long long int len; // size of shared memory object
char *addr;

if(argc != 3 || strcmp(argv[1], "--help") == 0)

printf("%s shm-name string\\n", argv[0]);
exit(EXIT_FAILURE);


fd = shm_open(argv[1], O_RDWR, 0); // open
if(fd == -1)
exit(EXIT_FAILURE);

len = strlen(argv[2]);
if(ftruncate(fd, len) == -1)// resize with strlen()
exit(EXIT_FAILURE);
printf("Resized to %ld bytes\\n", (long)len);

addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(addr == MAP_FAILED)
exit(EXIT_FAILURE);

if(close(fd) == -1)
exit(EXIT_FAILURE);

printf("copying %ld bytes\\n", (long)len);
memcpy(addr, argv[2], len); // write to shm
exit(EXIT_SUCCESS);

【Linux CPOSIX 共享内存使用】向共享内存对象 ??demo_shm??? 写入字符 ??hello???。共享对象大小变为 5 的原因是 ??ftruncate()??? 系统调用根据写入内容的长度改变共享对象大小的缘故。

读出
#include < stdio.h>
#include < stdlib.h>
#include < unistd.h>
#include < fcntl.h>
#include < sys/mman.h>
#include < sys/stat.h>
#include < getopt.h>
#include < string.h>


int main(int argc, char *argv[])

int fd;
char *addr;
struct stat sb;

if(argc != 2 || strcmp(argv[1], "--help") == 0)

printf("%s shm-name string\\n", argv[0]);

    推荐阅读