Linux IPC实践(10)

1.创建/获取一个共享内存

#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);

参数:

name:共享内存名字;

oflag:与open函数类型,可以是O_RDONLY,O_WRONLY,O_RDWR,还可以按位或上O_CREAT,O_EXCL,O_TRUNC.

mode:此参数总是需要设置,如果oflag没有指定O_CREAT,则mode可以设置为0;

返回值:

成功:返回一个文件描述符;

失败:返回-1;

注意-PosixIPC名字限制:

1.必须以”/”开头,并且后面不能还有”/”,形如:/file-name;

2.名字长度不能超过NAME_MAX

3.链接时:Linkwith-lrt.

/** 示例: 共享内存的打开与关闭 **/int main(int argc,char *argv[]){int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666);if (shmid == -1)err_exit("shmget error");cout << "share memory open success" << endl;close(shmid);}

2.修改共享内存大小

int ftruncate(int fd, off_t length);

该函数不仅可用于修改共享内存大小,而且可以用于修改文件大小

/** 示例: 修改共享内存大小将其修改为一个Student结构体的大小**/struct Student{char name[32];int age;};int main(int argc,char *argv[]){int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666);if (shmid == -1)err_exit("shmget error");if (ftruncate(shmid, sizeof(Student)) == -1)err_exit("ftruncate error");cout << "share memory change size success" << endl;close(shmid);}

3.获取共享内存状态

int fstat(int fd, struct stat *buf);

该函数不仅可用于获取共享内存状态,而且可以用于获取文件状态,与前面曾经讲述过的stat,lstat类型;

//stat结构体struct stat{dev_tst_dev;/* ID of device containing file */ino_tst_ino;/* inode number */mode_t st_mode; /* protection */nlink_t st_nlink; /* number of hard links */uid_tst_uid;/* user ID of owner */gid_tst_gid;/* group ID of owner */dev_tst_rdev; /* device ID (if special file) */off_tst_size; /* total size, in bytes */blksize_t st_blksize; /* blocksize for filesystem I/O */blkcnt_t st_blocks; /* number of 512B blocks allocated */time_t st_atime; /* time of last access */time_t st_mtime; /* time of last modification */time_t st_ctime; /* time of last status change */};/** 示例: 获取共享内存的mode和size **/int main(int argc,char *argv[]){int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666);if (shmid == -1)err_exit("shmget error");if (ftruncate(shmid, sizeof(Student)) == -1)err_exit("ftruncate error");struct stat buf;if (fstat(shmid, &buf) == -1)err_exit("lstat error");// 注意: 获取权限时, 需要&上0777, 而且要以%o, 八进制方式打印printf("mode: %o\n", buf.st_mode&0777);printf("size: %ld\n", buf.st_size);close(shmid);}

4.删除一个共享内存对象

int shm_unlink(const char *name);//示例: int main(int argc,char *argv[]){shm_unlink("/xyz");}

5.共享内存的映射/卸载

#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);int munmap(void *addr, size_t length);

参数:

addr:要映射的起始地址,通常指定为NULL,让内核自动选择;

length:映射到进程地址空间的字节数,通常是先前已经创建的共享内存的大小;

prot:映射区保护方式(见下);

flags:标志(通常指定为MAP_SHARED,用于进程间通信);

fd:文件描述符(填为shm_open返回的共享内存ID);

offset:从文件头开始的偏移量(一般填为0);

prot

说明

PROT_READ

页面可读

PROT_WRITE

页面可写

PROC_EXEC

页面可执行

PROC_NONE

页面不可访问

flags

说明

MAP_SHARED

变动是共享的

MAP_PRIVATE

变动是私有的

MAP_FIXED

准确解释addr参数,如果不指定该参数,则会以4K大小的内存进行对齐

MAP_ANONYMOUS

建立匿名映射区,不涉及文件

mmap返回值:

成功:返回映射到的内存区的起始地址;

失败:返回MAP_FAILED;

注意:mmap失败返回EACCES错误的原因:

EACCESAfiledescriptorreferstoanon-regularfile.

OrMAP_PRIVATEwasrequested,butfdisnotopenforreading.

OrMAP_SHAREDwasrequestedandPROT_WRITEisset,butfdisnotopen

你要以乐观的态度看待这个世界,你会发现世界是如此得美好

Linux IPC实践(10)

相关文章:

你感兴趣的文章:

标签云: