zoukankan      html  css  js  c++  java
  • linux共享内存的使用

    linux共享内存和windows的共享内存逻辑上有很大区别,要注意一下几点

    1. shmget的第三个参数标识

    标识 描述
    IPC_EXCL 这个加入后,如果已经存在标识为key的共享内存则报错返回-1
    0 如果是0 的话,就可以实现,如果共享内存不存在则返回失败-1,否则直接创建返回成功
    0666 这个标识符很多人不知道啥意思,其实试试就知道了,它可以让你在普通用户下创建访问共享内存,如果没有这个标识,共享内存的创建和访问都必须在root用户下进行,参考《unix环境高级编程第二版》,里面有 #define SHM_MODE 0600 /* user read/write */

    2. 共享内存的回收

    共享内存想完全销毁,需要满足两个条件

    1. 应用计数为0,shmat/shmdt
    2. 标记为删除, shmctl
      如果引用计数不为0,你删除了,那么这个共享内存还在,还可以读取里面的值,但是共享内存的标记已经删除,所以后续程序无法打开,找不到共享内存
      如果引用计数为0,但是你没标记删除,那么共享内存标记和空间都还在,可以访问并读取内存,造成内存泄露,注意了

    3. 例子

    首先是创建共享内存

    /*
     File: sharemem.c
     Author: magicdmer
    */
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int main()
    {
    	void *shm_addr = NULL;
    	int shmid;	
    	key_t key;
    
        key=ftok("/usr/local/ve-viewer",10);  
    	if(key==-1)  
    	{  
        	perror("ftok error
    ");  
        	return 0;  
    	} 
    
    	perror("shmid:%u
    ",key);  
        
        /*
          这里要注意了,IPC_EXCL这个的作用是:如果存在这个共享内存了就返回失败
          如果不加这个,会一直成功,会直接打开已有的
        */
    	shmid = shmget(key,1,IPC_CREAT|IPC_EXCL);
    	if (shmid == -1)
    	{
    		perror("shmget error
    ");
    		return 0;
    	}
    	
    	shm_addr = shmat(shmid, NULL, 0);
    	if (shm_addr == -1)
    	{
    		perror("shmat error
    ");
    		return 0;
    	}
    
    	memcpy(shm_addr,"Y",1);
    
    	getchar();
    
    	if (shmdt(shm_addr) == -1)
    	{
    		perror("shmdt error
    ");
    		return 0;
    	}
    
    	if (shmctl(shmid, IPC_RMID, 0) == -1)
        {
            perror("shmctl error!
    ");
    		return 0;
        }
    
    	return 0;
    }
    

    然后是读写共享内存

    /*
     File: sharemem.c
     Author: magicdmer
    */
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int main()
    {
    	void *shm_addr = NULL;
    	int shmid;	
    	key_t key;
    
        key=ftok("/usr/local/ve-viewer",10);  
    	if(key==-1)  
    	{  
        	perror("ftok error
    ");  
        	return 0;  
    	} 
    
        
        //这里要注意了,最后一个flag设置成0,这样,如果共享内存不存在就会报错,不然即使没有也直接创建了
    	shmid = shmget(key,1,0);
    	if (shmid == -1)
    	{
    		perror("shmget error
    ");
    		return 0;
    	}
    
    	shm_addr = shmat(shmid, NULL, 0);
    	if (shm_addr == (void *)-1)
    	{
    		perror("shmat error!");
    		return 0;
    	}
    
    	char tmp[10];
    	bzero(tmp, 10);
    	memcpy(tmp,shm_addr,1);
    	printf("read from shared memory:%s
    ",tmp);
    	
    	getchar();
    	
    	bzero(tmp, 10);
    	memcpy(tmp,shm_addr,1);
    	printf("read from shared memory:%s
    ",tmp);
    
    	if (shmdt(shm_addr) == -1)
    	{
    		perror("shmdt error
    ");
    		return 0;
    	}
    
    }
    
  • 相关阅读:
    软件体系架构复习要点
    Operating System on Raspberry Pi 3b
    2019-2020 ICPC North-Western Russia Regional Contest
    2019 ICPC ShenYang Regional Online Contest
    2019 ICPC XuZhou Regional Online Contest
    2019 ICPC NanChang Regional Online Contest
    2019 ICPC NanJing Regional Online Contest
    Codeforces Edu Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div.1+Div.2)
    AtCoder Beginning Contest 139
  • 原文地址:https://www.cnblogs.com/magicdmer/p/12792685.html
Copyright © 2011-2022 走看看