文章目录
- 第一章
- 1、IPC对象的持续性(声明周期)
- 2、errno值
- 第二章:Posix IPC
- 1、IPC权限
- 第三章:System V IPC
- 1、key_t键 和 ftok 函数
- 2、System V IPC 对象结构体 ipc_perm
- 3、IPC权限
- 4、标识符重用
- 5、ipcs 和 ipcrm
- 共享内存
- mmap munmap msync
- 匿名空间映射
- Posix共享内存
- shm_open、 shm_unlink
- fturncate
- fstat
- 创建共享内存的步骤
- 共享内存的使用
- System V 共享内存
- System V 共享内存信息结构
- shmget函数
- shmat
- shmdt
- shmctl
- posix和system v共享内存的区别
- 问题记录
- 1、posix IPC 和 System V IPC 有和区别和联系 ?
- 2、指定权限受到当前进程的文件模式创建掩码修正??
- 3、errno的定义
第一章
1、IPC对象的持续性(声明周期)
随进程持续的IPC:一直存在直到最后一个使用IPC对象的进程关闭为止,如管道和FIFO;
随内核持续的IPC:一直存在到内核重新自举或者显示删除,如System V 消息队列、信号量…;
随文件系统持续的IPC:一直存在到显示删除IPC对象;
使用IPC时要注意IPC对象的持续性。
2、errno值
Linux中系统调用的错误都存储于 errno中,errno由操作系统维护,每个进程都有,存储就近发生的错误,即下一次的错误码会覆盖掉上一次的错误。
第二章:Posix IPC
posix ipc 包括: posix消息队列(mqueue.h)、posix信号量(semaphore.h)、posix共享内存(sys/mman.h),并以路径名作为标识,创建或打开xxopen
1、IPC权限
第三章:System V IPC
System V IPC 包括:System V消息队列(sys/msg.h)、System V信号量(sys/sem.h)、System V共享内存(sys/shm.h),创建或打开xxxget
1、key_t键 和 ftok 函数
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
ftok函数把一个已经存在的路径名(参数1)和 一个整数标识(参数2 id)转换成一个key_t值,称为IPC键(至少为32位)。
使用IPC的进程将给定的pathname和id转化成一个IPC键。
IPC键的组成:pathname指向文件的stat->st_dev + stat->st_ino + id[7:0].
id的[7:0]位不能全为0,否则ftok函数行为无效
若pathname或进程无访问权限ftok返回-1.
2、System V IPC 对象结构体 ipc_perm
/* Obsolete, used only for backwards compatibility and libc5 compiles */
<sys/ipc.h>
struct ipc_perm
{__kernel_key_t key;//键__kernel_uid_t uid;//用户id__kernel_gid_t gid;//用户组id__kernel_uid_t cuid;//创建者用户id__kernel_gid_t cgid;//创建者组id__kernel_mode_t mode;//读写权限unsigned short seq;//槽位使用情况序列
};
3、IPC权限
4、标识符重用
5、ipcs 和 ipcrm
共享内存
IPC中最快的方式
mmap munmap msync
mmap将一个文件或者posix共享内存区对象映射到调用进程的地址空间。使用该函数的目的有:
1)对普通文件提供内存映射IO
2)对特殊文件提供匿名内存映射
3)使用shm_open以提供无亲缘关系的进程之间的posix共享内存
#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);#include <sys/mman.h>int msync(void *addr, size_t length, int flags);
参数:
mmap
addr:映射到进程中的内存首地址,NULL,由内核指定
length:映射空间大小
prot:映射内存的保护参数,读、写、执行、不可访问
flags:共享、私有、FIXED
fd:文件描述符
offset:文件偏移位置
return:成功返回映射空间首地址,失败MAP_FAILED设置errno
mmap成功后可以关闭文件描述符
munmap
return:成功返回0,失败返回-1
msync
flags:同步方式,同步写、异步写、使高速缓存失效
return:成功返回0,失败返回-1
匿名空间映射
不使用文件进行空间映射,匿名空间映射可以在父子进程之间实现共享内存,且不需要打开文件。
mmap flags参数添加MAP_ANON,fd 为-1.
Posix共享内存
无亲源关系的进程间共享内存区
1)内存映射文件
2)共享内存区对象
这两种方法都需要使用mmap函数,不同之处在于文件描述符的不同一个由open得到,一个由shm_open得到,随内核持续特性
shm_open、 shm_unlink
#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);int shm_unlink(const char *name);
参数:
shm_open
name:共享内存对象路径
oflag和mode参数参考open函数,oflag至少未可读。
return:成功返回文件描述符,失败-1
共享内存对象路径可由任意进程调用
shm_unlink:
删除一个共享内存区对象
删除名字不会影响已经打开共享内存的进程,知道共享内存使用完毕(引用为0);
不过删除后open会失败;
return:成功返回0,失败-1
fturncate
调整不同文件或者共享内存的大小
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
对于普通文件:
大小大于length,则多余的丢弃,小于则是否增加文件大小未说明
对于共享内存:调整未length大小
fstat
通过文件描述符获取共享内存的信息
创建共享内存的步骤
1)shm_open打开或创建一个共享内存,返回文件描述符
2)ftruncate调整共享内存大小
3)mmap映射共享内存到进程
共享内存的使用
1)shm_open打开一个共享内存,返回文件描述符
2)fstat获取大小
3)根据大小mmap映射共享内存到进程
4)根据大小写入或读取(非系统调用)
对共享内存的读写也需要使用某种方式同步
创建时先使用shm_unlink 防止对象已经存在
System V 共享内存
System V 共享内存信息结构
struct shmid_ds {struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */__kernel_time_t shm_atime; /* last attach time */__kernel_time_t shm_dtime; /* last detach time */__kernel_time_t shm_ctime; /* last change time */__kernel_ipc_pid_t shm_cpid; /* pid of creator */__kernel_ipc_pid_t shm_lpid; /* pid of last operator */unsigned short shm_nattch; /* no. of current attaches */unsigned short shm_unused; /* compatibility */void *shm_unused2; /* ditto - used by DIPC */void *shm_unused3; /* unused */
};
shmget函数
#include <sys/ipc.h>#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
参数
打开或创建一个共享内存对象
key:ftok的返回值或者IPC_PRIVATE
size:创建时为一个大于0的值,操作已存在对象时应指定为0
shmflg:权限值
return:成功返回共享内存对象(标识符),失败-1
shmat
#include <sys/types.h>
#include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
通过shmget打开或创建一个共享内存对象后使用shmat将对象附加到进程的地址空间
shmid:shmget的返回值(对象标识符)
shmaddr:为非空的指针时返回地址取决于shmflg是否指定了SHM_RND,未指定地址由该参数决定,指定的话返回地址由该参数向下舍入一个SHMLBA值。
若为空指针,返回地址由系统决定,系统推荐方法
shmflg:读写权限
返回值:成功返回共享内存对象映射的首地址,失败-1
shmdt
int shmdt(const void *shmaddr);
参数
断开进程对共享内存的使用,在进程结束时自动断开
shmaddr:shmat的返回值
return:成功返回0,失败-1
shmctl
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
提供多种对共享内存的操作
shmid:shmget的返回值
cmd:命令值
IPC_RMID 删除对象并回收
IPC_SET 通过buf设置对象信息
IPC_STAT 通过buf返回对象信息
buf:共享内存对象信息结构体
return:成功返回0,失败-1
posix和system v共享内存的区别
1)system v共享内存大小在创建时固定,posix可以通过ftruecate修改
问题记录
1、posix IPC 和 System V IPC 有和区别和联系 ?
Posix Portable Operation System Interfice 可移植操作系统接口
POSIX接口和System V接口是用于多线程和进程间通信的两种主要编程接口。它们各自有不同的特点、功能和适用场景。以下是对这两种接口的详细介绍及其异同点。
2、指定权限受到当前进程的文件模式创建掩码修正??
umask函数或命令