(1)文件存儲映射I/O(Memory-mapped I/O)
? ? ? ? ? 一個磁盤文件與存儲空間中的一個緩存區相對應,這樣可以在不適合read/write函數的情況下,使用地址(指針)完成I/O操作。具體實現通過內核指定一個文件映射到存儲區域中,這個映射可以通過mmap來實現。
? ? ? ? ? mmap函數原型及頭文件
? ? ? ? ? ? ? ? ??
? ? ? ? ?函數參數:addr:建立映射區的首地址,由linux內核決定,直接賦值NULL即可;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?length:想要建議映射區的大小(應該比磁盤文件小)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?prot:映射區權限,有PROT_READ,PROT_WRITE,PROT_READ|PROT_WRITE(權限小于文件的權限)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?flags:標志位參數,通常用來設置更新物理區域,設置共享,創建匿名映射區
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MAP_SHARED:映射區所做的操作會反應到磁盤上
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MAP_PRIVATE:映射區所做的操作會不反應到磁盤上
? ? ? ? ? ? ? ? ? ? ? ? ? ? fd:磁盤文件的文件描述符
? ? ? ? ? ? ? ? ? ? ? ? ? ? offset:映射文件的偏移(4K整數倍,因為內存的最小大小是4K)
? ? ? ? ?返回參數:成功,返回映射區首地址;失敗:返回MAP_FAILED宏(一定要檢查再使用)
? ? ? ? 與mmap相對的,有一個函數munmap用來回收mmap申請的映射空間
? ? ? ? ?函數原型及頭文件: 成功返回0,失敗返回-1.
? ? ? ? ? ?
? ? ? ? ?mmap和munmap函數使用時注意事項:
(2)mmap父子間進程通信
? ? ? ? ?父子間等有血緣關系的進程可以通過mmap來建立映射,只需要改變創建映射區的標志位參數flags.
? ? ? ? ? ? ? ? ?MAP_SHARED(共享映射)? 父子進程共享映射區
? ? ? ? ? ? ? ? ?MAP_PRIVATE(私有映射)? 父子間各自獨占映射區
實現父子進程通信,父進程穿件映射區,然后fork子進程,修改映射區的內容,父進程再讀取映射區內容,檢查是否修改。
? ? ? ?父子進程共享:打開的文件和mmap建立的映射區(MAP_SHARED)
(3)匿名映射
? ? ? ? ?父子進程間通信建立一個映射區通常需要打開一個文件,創建好再unlink(刪除文件的臨時目錄項,以便在所有使用這個文件的進程關閉后刪除文件),close等操作,比較麻煩,可以采用匿名映射來代替臨時文件,具體操作如下:
? ? ? ? mmap(NULL.size(任意大小),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
? ? ? ? MAP_ANONYMOUS(MAP_ANON)宏是linux操作系統所特有的宏。
? ? ? ?在類unix系統中可以使用以下操作完成匿名映射區的建立。
? ? ? ?fd=open("/dev/zero",O_RDWR);
? ? ? p=mmap(NULL,size,PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0);
(4)mmap無血源關系實現進程間通信
? ? ? ? mmap是內核借助文件創建一個映射區,多個進程可以通過利用該映射區來完成數據傳遞,因此無血緣關系的進程也可以進行通信,只需要設置對應的flags即可(設置成MAP_SHARED)
實現非血源關系的進程間的通信,一個進程實現寫映射區操作,一個實現讀映射區操作(先完成寫進程操作,再完成讀進程操作)。
寫進程操作:
讀進程操作