mmap提供父子進程間的共享內存區的列子:
(1)使用內存映射文件;
(2)使用4.4BSD 匿名內存映射;
(3)使用 /dev/zero 匿名內存映射。
POSIX 提供了兩種在無親緣關係進程間共享內存區的方法:
(1)內存映射文件:由open函數打開,由mmap函數把得到的描述符映射 到當前進程地址空間中的一個文件。
(2)共享內存區對象:由shm_open 打開一個Posix IPC名字,所返回的描述符由mmap函數映射到當前進程的地址空間。
差別在於:獲取描述符的手段。Posix 把兩者合稱爲內存區對象。
shm_open、shm_unlink函數
Posix共享內存區涉及兩個步驟要求:
(1)指定一個名字參數調用shm_open,以創建一個新的共享內存區對象或打開一個已存在的共享內存區對象。
(2)調用mmap把這個共享內存區映射到調用進程的地址空間。
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
int shm_open(const char *name, int oflag, mode_t mode);
// 若成功則爲非負描述符,出錯-1
int shm_unlink(const char *name);
// 成功0, 出錯-1
Link with -lrt.
ftruncate、fstat 函數
處理mmap的時候,普通文件或共享內存區對象的大小都可以通過調用 ftruncate 修改。
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
// 返回:成功爲0, 出錯爲-1
Posix就該函數對普通文件和共享內存區對象的處理定義有如下不同:
1、普通文件:如果該文件的大小大於length參數,額外的數據就被丟棄掉。如果該文件的大小小於length,那麼該文件是否修改以及其大小是否增長是未加說明的。
2、共享內存區對象:ftruncate把該對象的大小設置成length字節。
我們調用ftruncate來指定新創建的共享內存區對象的大小,或者修改已存在的對象的大小。當打開一個已存在的共享內存區對象時,可調用fstat來獲取有關該對象的信息。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
// 成功爲0,出錯-1
int lstat(const char *pathname, struct stat *buf);
#include <fcntl.h> /* Definition of AT_* constants */
#include <sys/stat.h>
int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags);
stat 結構:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* file type and mode */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
當 fd 代指一個共享內存區對象時,只有四個成員含有信息。st_mode、st_uid、st_gid、st_size。