POSIX共享内存

POSIX共享内存不须要自己手动挂载,仅仅要打开成功,就会自己主动挂载.一般挂载在 /dev/shm 文件夹下

cd /dev/shm

od -c xyz

1. shm_open 函数
功能:用来创建或打开一个共享内存对象
原型:
    int shm_open(const char* name,int oflag,mode_t mode);
參数:
    name:共享内存对象的名字
    oflag:与open 函数类似,能够是O_RDONLY,O_RDWR,还能够按位或上O_CREAT,O_EXCL,O_TRUNC等.
    mode:此參数总是须要设置,假设oflag没有指定 O_CREAT, 能够指定为0;
返回值: 成功返回非负整数文件描写叙述符;失败返回-1

2. ftruncate
功能:改动共享内存对象大小
原型: int ftruncate(int fd,off_t length);
參数:
    fd:文件描写叙述符
    length:长度
返回值: 成功返回0,失败返回-1

3.fstat
功能:获取共享内存对象信息
原型:
    int fstat(int fd,struct stat *buf);
參数:
    fd: 文件描写叙述符
    buf: 返回共享内存状态
返回值: 成功返回0,失败返回-1

4. shm_unlink函数
功能:删除一个共享内存对象
原型: int  shm_unlink(const char* name);
參数:
    name:共享内存对象的名字
返回值:
    成功返回0,失败返回-1;

5.mmap
功能:将共享内存对象映射到进程地址空间.
原型:
    void *mmap(void *addr,size_t len,int prot,int flags,int fd,off_t offset);
參数:
    addr:要映射的起始地址,通常指定为NULL,让内核自己主动选择
    len: 映射到进程地址空间的字节数
    prot: 映射区保护方式
    flags: 标志
    fd: 文件描写叙述符
    offset: 从文件头開始的偏移量
返回值: 成功返回映射到的内存区的起始地址,失败返回-1

注意:

ERRORS
       EACCES A  file descriptor refers to a non-regular file.  Or MAP_PRIVATE
              was requested, but fd is not open for  reading.   Or  MAP_SHARED
              was  requested  and  PROT_WRITE  is  set,  but fd is not open in
              read/write (O_RDWR) mode.  Or PROT_WRITE is set, but the file is
              append-only
.

shm_open.c

#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define ERR_EXIT(M) 
		do 
		{	
				perror(M); 
				exit(EXIT_FAILURE); 
		}while(0);

typedef struct stu
{
	char name[32];
	int age;
}STU;

int main(void)
{
	int shmid;
	//用来创建或打开一个共享内存对象
	shmid = shm_open("/xyz",O_CREAT | O_RDWR,0666);
	if(shmid == -1)
			ERR_EXIT("shm_open err");
	printf("shm_open success
");
	if( ftruncate(shmid,sizeof(STU)) == -1 ) //改动共享内存对象大小
		ERR_EXIT("ftruncate");
	
	struct stat buf; 
	if(fstat(shmid,&buf) == -1)  /// get file status
		ERR_EXIT("fstat err");
	printf("size=%ld mode=%o
",buf.st_size,buf.st_mode & 0777);
	
	
	close(shmid);  // 只须要一个close就能够关闭
	return 0;
}

shm_unlink.c

#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define ERR_EXIT(M) 
		do 
		{	
				perror(M); 
				exit(EXIT_FAILURE); 
		}while(0);


int main(void)
{
	shm_unlink("/xyz");
	return 0;
}
 

shm_write.c

#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define ERR_EXIT(M) 
		do 
		{	
				perror(M); 
				exit(EXIT_FAILURE); 
		}while(0);

typedef struct stu
{
	char name[32];
	int age;
}STU;

int main(void)
{
	int shmid;
	shmid = shm_open("/xyz",O_RDWR,0); // 这里必须是O_RDWR才干映射成功
	if(shmid == -1)
		ERR_EXIT("shm_open err");
	printf("shm_open succ
");
	struct stat buf;
	if(fstat(shmid,&buf) == -1)
		ERR_EXIT("fstat err");
	STU *p;
	//将共享内存对象映射到进程地址空间.
	p = mmap(NULL,buf.st_size,PROT_WRITE,MAP_SHARED,shmid,0);
	if(p == MAP_FAILED)
		ERR_EXIT("mmap err");
	strcpy(p->name,"cjl");  // 依据映射的地址,写入数据
	p->age = 20;
	
	close(shmid);  // 只须要一个close就能够关闭
	return 0;
}

shm_read.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<string.h>

#define ERR_EXIT(m) 
    do { 
        perror(m); 
        exit(EXIT_FAILURE); 
    } while(0)

typedef struct stu
{
    char name[32];
    int age;
} STU;

int main(void)
{
    int  shmid;
    shmid = shm_open("/xyz", O_RDONLY, 0);
    if (shmid == -1)
        ERR_EXIT("shm_open");

    struct stat buf;
    if (fstat(shmid, &buf) == -1)
        ERR_EXIT("fstat");

    printf("size=%ld, mode=%o
", buf.st_size, buf.st_mode & 0777);

    STU *p;
    p = (STU *)mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, shmid, 0);
    if (p == MAP_FAILED)
        ERR_EXIT("mmap");


    printf("name=%s age=%d
", p->name, p->age);
    close(shmid);
    return 0;
}

Makefile

.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN=shm_open  shm_unlink shm_write shm_read
all:$(BIN)
%.o:%.c
	$(CC) $(CFLAGS) -c $< -o $@
shm_open:shm_open.o
	$(CC) $(CFLAGS)  $^ -o $@ -lrt
shm_unlink:shm_unlink.o
	$(CC) $(CFLAGS)  $^ -o $@ -lrt
shm_write:shm_write.o
	$(CC) $(CFLAGS)  $^ -o $@ -lrt
shm_read:shm_read.o
	$(CC) $(CFLAGS)  $^ -o $@ -lrt
clean:
	rm -f  *.o $(BIN) 


原文地址:https://www.cnblogs.com/lytwajue/p/7067302.html