【UNIX】什麼是IPC對象以及共享內存

sys V 的IPC 對象:對於內核中創建的文件對象,就是文件標識符(它引用了文件對象的全部信息)在進程中文件描述符一般使用當前最小可用值。

對於IPC標識符返回的是索引的整數值,它是全局變量的流水號,在系統中唯一分配的,若果在創建的IPC對象沒有關閉,他會全局存在,只有在系統關閉的時候才關閉,這樣會造成內存空間的資源被佔用。

爲了進程之間交換信息,內核專門留了一塊內存空間,由進程映射到各自進程私有空間。

【共享內存的實現】:

1)創建/打開共享內存,這裏的創建/打開和文件的創建/打開差不多,只是換了一種說法,都是在內核空間創建有一個緩存空間,提供要交換的信息

2)映射共享內存的內容,就是把共享內存的內容映射到進程的地址空間用於訪問

3)撤銷共享內存的映射,就是解掛的含義,進程不需要再訪問共享內存的時候

4)刪除共享內存的對象,就是內核系統在內存空間創建的文件描述符

具體代碼如下:

/*
* key_t ftok(const char *pathname,int proj_id)
* ID是約好的ID號,可以是兩個進程去訪問, 
*_key(IPC_PRIVATE)父子進程之間的KEY值,不需要通過ftok函數得到
* KEY值表示IPC標識符
*

* int shmget (key_t key,int size,int shmflag);
* 這裏的shmget 就像文件IO中的open函數
* key值就是ftok函數返回的值,等同以fork函數的fd
* size表示共享內存開的大小
* shmflag 表示open的權限位

* int shmat(int shmid,const void *shmaddr,int shmflag)  (attch掛載的含義)
* shmid表示要映射的內存共享去的標識符(shmget 返回標識符)
* shmaddr表示共享內存區要映射到進程空間指定地址(賦空NULL表示系統自動完成映射)
* shmflag 設置內存空間的讀寫權限(SHM_RDONLY,0表示共享內存可讀寫)
*

* int shmdt(const void *shmaddr)
* 這裏撤銷映射地址空間的shmaddr是shmat 函數的返回地址
* shmadd = (char *)shmat (shmid,NULL,0)
*

* int shmctl(int shmid,int cmd,struct shmid_ds *buf)
* shmid 是要操作的共享內存標識符
* cmd 表示獲取對象的屬性,一般是刪除對象IPC_RMID
* buf 表示指定IPC_STAT/IPC_SET時用以保存/設置屬性 (一般賦空NULL)
*
/

#include 
#include 	/* shmget, shmctl */
#include 	/* fork */
#include 	/* printf */
#include 	/* exit */

#define BUFSZ		2048

int main()
{
	pid_t	pid;
	int	shmid;
	
	if((shmid = shmget(IPC_PRIVATE, BUFSZ, 0666)) < 0){
			perror("shmget");
			exit(-1);
	}
	printf("process(pid=%d) created shared-memory id=%d\n",
			getpid(), shmid);
	
	if ((pid = fork()) < 0) {
		perror("fork error");
		exit(1);
	}
	
	if (pid == 0) {
		printf("process(pid=%d) inherited shared-memory id=%d\n",
			getpid(), shmid);
					
	} else {
		sleep(1); /* just for display */
		printf("ready to show IPC share memory status?");
		getchar();

		printf("two processes get the same shared memory object\n");
		printf("------ Shared Memory Segments --------\n");
		printf("key        shmid      owner      "\
			"perms      bytes      nattch     status\n");
		system("ipcs -m | grep 666");
		
		printf("ready to terminate?");
		getchar();
		
		if (-1 == shmctl(shmid, IPC_RMID, NULL)) {
			perror("shmctl error");
		}
		
		printf("removed shared-memory\n");
		printf("------ Shared Memory Segments --------\n");
		printf("key        shmid      owner      "\
			"perms      bytes      nattch     status\n");
		system("ipcs -m | grep 666");

	}

	exit(0);
}
/*
* char *shmadd
* shmadd = (char *)shmat(shmid,NULL,0) <(char *)0 映射地址空間
* shmdt(shmadd) 撤銷/解除進程與共享空間的映射關係
* shmctl(shmid,IPC_RMID,NULL) 刪除IPC共享內存空間
*/

發佈了65 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章