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\n");  
    	return 0;  
	} 

	perror("shmid:%u\n",key);  
    
    /*
      這里要注意了,IPC_EXCL這個的作用是:如果存在這個共享內存了就返回失敗
      如果不加這個,會一直成功,會直接打開已有的
    */
	shmid = shmget(key,1,IPC_CREAT|IPC_EXCL);
	if (shmid == -1)
	{
		perror("shmget error\n");
		return 0;
	}
	
	shm_addr = shmat(shmid, NULL, 0);
	if (shm_addr == -1)
	{
		perror("shmat error\n");
		return 0;
	}

	memcpy(shm_addr,"Y",1);

	getchar();

	if (shmdt(shm_addr) == -1)
	{
		perror("shmdt error\n");
		return 0;
	}

	if (shmctl(shmid, IPC_RMID, 0) == -1)
    {
        perror("shmctl error!\n");
		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\n");  
    	return 0;  
	} 

    
    //這里要注意了,最后一個flag設置成0,這樣,如果共享內存不存在就會報錯,不然即使沒有也直接創建了
	shmid = shmget(key,1,0);
	if (shmid == -1)
	{
		perror("shmget error\n");
		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\n",tmp);
	
	getchar();
	
	bzero(tmp, 10);
	memcpy(tmp,shm_addr,1);
	printf("read from shared memory:%s\n",tmp);

	if (shmdt(shm_addr) == -1)
	{
		perror("shmdt error\n");
		return 0;
	}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM