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共享內存空間
*/