Posix Ipc
ipc对象持久性
- 进程持久性:具有这种持久性的对象在持有它的最后一个进程关闭了该对象为止
- 内核持久性:这种IPC对象一直存在直到内核重新自举或显示删除该对象为止
- 文件系统持久性:具有这种持久性的对象只有在它被显式删除时才会消失。即使内核重新自举该对象还保持(POSIX消息队列,信号量,共享内存如果是使用映射文件实现的,那么他们就是随文件系统持续的)。少有进程能不受系统重启的影响;而且使用文件系统持久性也可能会降低该IPC机制的性能
管道或FIFO尽管是随进程持续而不是随内核持续,但是管道中的数据在内核中维护,最后一个将某个管道打开着用于读的进程关闭该管道后,内核将丢弃所有的数据并删除该管道
类型 | 持久性 |
管道 FIFO |
进程持久性 进程持久性 |
Posix互斥锁 Posix条件变量 Posix读写锁 Fcntl记录锁 |
进程持久性 进程持久性 进程持久性 进程持久性 |
Posix消息队列 Posix命名信号量 Posix信号量 Posix共享内存 |
内核持久性 内核持久性 进程持久性 内核持久性 |
System V消息队列 System V信号量 System V共享内存 |
内核持久性 内核持久性 内核持久性 |
TCP socket UDP socket Unix域socket |
进程持久性 进程持久性 进程持久性 |
命名空间
当两个或多个无亲缘关系的进程使用某种类型的ipc对象交换彼此的信息时,ipc必须有一种某种形式的名字或标识符
消息队列,信号量,共享内存都可以是用路径名标示,这些名字即可以是文件系统的真实名字也可能不是
- 他必须符合已有路径规则,最多由PATH_MAX个字节构成,包括结尾的空字符
- 如果以斜杠开头,那么对这些函数的不同调用将访问同一个队列,如果他不以斜杠开头,那么效果取决于实现
- 名字中额外的斜杠符的解释由实现定义(名字必须以一个斜杠开头,并且不能在含有任何其他斜杠符,必须在根目录中有写权限)
- 当创建一个新的消息队列,信号量或共享内存区对象时,其用户id被设置为当前进程的有效用户id,信号量或共享内存区对象的组id被设置为当前进程的有效组id或某个系统默认的组id,新消息队列对象的组id被设为当前进程的有效组id,由open新创建的文件的组id或者是当前进程的有效组id,或者是该文件所在的目录的的组id,但是ipc函数不能假定系统为ipc创建一个在文件系统中的路径
S_TYPEISMQ(buf)
S_TYPEISSEM(buf)
S_TYPEISShM(buf)
这三个宏他们的单个参数是指向某个stat的结构指针,其内容由fstat,lstat或stat这三个函数填入,如果所指的IPC对象(消息队列,信号量,共享内存)是作为一种哦特殊的文件了型实现的,而且所指的stat结构访问这样的文件类型,那么这三个宏计算出一个非零值,否则,计算出的的值为0
ipc权限
unix内核执行权限测试
- 如果当前进程的有效用户id为0(超级用户),允许访问
- 在当前进程的有效用户id等于该ipc对象的属主id的前提下,如果相应的用户访问权限位(解释:如果当前进程为读访问而打开ipc对象,那么用户读权限位必须设置;如果当前进程为写访问而打开ipc对象,那么用户写权限位必须设置)已设置,那就允许访问,否则拒绝访问(即:如果当前进程拥有某个ipc对象,那么访问权的授予与拒绝只依赖用户访问权限——组访问权限不会考虑,类似,如果当前进程不拥有该ipic对象,但它属于某个合适的组,那么访问权限的授予与拒绝只依赖于组访问权限——其他用户访问权限绝不会考虑)
- 在当前进程的有效组id或它的某个辅助组id等于该ipc对象的组id的前提下,如果相应的组id访问权限位已设置,那么允许访问,否则拒绝访问
- 如果相应的其他用户访问相应的权限位已设置,那么就允许访问,否则拒绝访问
调用fork,exec,_exit对IPC对象影响
类型 | fork | exec | _exit |
管道和FIFO | 子进程获得父进程的所有打开的描述符的拷贝 | 除非描述符的FD_CLOSEXEC比特被置位了,否则描述符保持打开状态 | 所有描述符都被关闭,在描述符最后一次被关闭时,管道或FIFO中的数据会被删除 |
Posix消息队列 | 子进程获得父进程的所有打开的消息队列描述符的拷贝 | 所有打开的消息队列的描述符都被关闭 | 所有打开的消息队列的描述符都被关闭 |
System V消息队列 | 没影响 | 没影响 | 没影响 |
Posix互斥锁和条件变量 | 如果在共享内存中并且设置了进程共享属性则就被共享 | 除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失 | 除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失 |
Posix读写锁 | 如果在共享内存中并且设置了进程共享属性则就被共享 | 除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失 | 除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失 |
Posix(基于内存的)信号量 | 如果在共享内存中并且设置了进程共享属性则就被共享 | 除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失 | 除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失 |
Posix命名信号量 | 在父进程被打开的在子进程中仍保持打开 | 所有被打开的都将被关闭 | 所有被打开的都将被关闭 |
System V信号量 | 所有的semadj的值在子进程中被设置为0 | 所有的semadj的值被传递给新的程序 | 所有的semadj的值被加到相应的信号量上 |
记录锁 | 父进程持有的锁不会被子进程所继承 | 只要描述保持打开,锁就不会因为exec的动作而变化 | 所有被进程持有的锁都会被释放 |
mmap共享内存 | 父进程的共享内存被子进程保留 | 共享内存被unmapped | 共享内存被unmapped |
Posix共享内存 | 父进程的共享内存被子进程保留 | 共享内存被unmapped | 共享内存被unmapped |
System V共享内存 | 父进程中已连接上的共享内存被子进程保留 | 共享内存被deattached | 共享内存被deattached |
可以用ipcrm命令删除系统中的残留资源。