zoukankan      html  css  js  c++  java
  • 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) 


  • 相关阅读:
    通过命令行配置samba服务
    新版python logging 封装,支持同时向console,file,socket输出
    python多进程管理DEMO
    注意tornado中的日志操作
    一个简单的python日志服务器
    NoVNC的使用、websockify以及VNC截图
    Oracle——distinct的用法
    C# Excel数据转化为Datatable
    C# winform 无API函数实现系统快捷键
    [转]C# WInForm 无框窗体移动
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7067302.html
Copyright © 2011-2022 走看看