您的当前位置:首页正文

POSIX 进程间通信 (可移植操作系统接口)

来源:九壹网

1、什么是POSIX标准

Portable Operating System Interface for Computing System.

他是一个针对操作系统(准确地说是针对类Unix操作系统)的标准化协议。

这个协议是对操作系统服务接口的标准化,从而保证了应用程序在源码层次的可移植性。

如今主流的Linux系统都做到了兼容POSIX标准。

2、POSIX标准的C/C++库

C/C++的标准库是指ANSI C/C++定义的标准库,这个是构成标准C/C++语言的基础。简称libc/libc++,常见的libc/libc++的实现有:UNIX C/C++,GUN C/C++,MicroSoft Visual C/C++
在标准C/C++库基础上,兼容POSIX协议的C/C++库就是POSIX标准的C/C++库,这些C/C++库可以直接操作符合POSIX标准的操作系统调用。
常见的POSIX标准C/C++库有:
2.1 BSD,这个库是AOSP使用的标准C库。
2.2 Bionic,这个是BSD的衍生库,用于NDK开发
2.3 UNIX C/C++,GUN C/C++,MicroSoft Visual C/C++

POSIX 进程间通信 (Interprocess Communication, IPC) 是 System V 进程间通信的变体。它是在 Solaris 7 发行版中引入的。与 System V 对象类似,POSIX IPC 对象的属主、属主的组以及其他用户具有读取和写入权限,但是没有执行权限。POSIX IPC 对象的属主无法将对象分配给其他属主。POSIX IPC 包括以下功能:

  • 消息允许进程将已格式化的数据流发送到任意进程。

  • 信号量允许进程同步执行。

与 System V IPC 接口不同,POSIX IPC 接口均为多线程安全接口。

POSIX 消息

下表中列出了 POSIX 消息队列接口。

表 7-2 POSIX 消息队列接口

接口名称
目的
连接到以及(可选)创建命名消息队列
结束到开放式消息队列的连接
结束到开放式消息队列的连接,并在最后一个进程关闭此队列时将其删除
将消息放入队列
在队列中接收(删除)最早且优先级最高的消息
通知进程或线程消息已存在于队列中
设置或获取消息队列属性

POSIX 信号量

POSIX 信号量比 System V 信号量轻得多。POSIX 信号量结构定义单个信号量,而不是定义最多包含 25 个信号量的数组。

POSIX 信号量接口如下所示。

连接到以及(可选)创建命名信号量

初始化信号量结构(在调用程序内部,因此不是命名信号量)

结束到开放式信号量的连接

结束到开放式信号量的连接,并在最后一个进程关闭此信号量时将其删除

初始化信号量结构(在调用程序内部,因此不是命名信号量)

将信号量的值复制到指定整数中

当其他进程拥有信号量时进行阻塞,或者当其他进程拥有信号量时返回错误

递增信号量计数

POSIX 共享内存

POSIX 共享内存实际上是映射内存的变体(请参见)。二者的主要差异在于:

  • 打开共享内存对象应使用 ,而不是通过调用 。

  • 关闭和删除对象应使用 ,而不是通过调用 ,此调用不删除对象。

 中的选项数实际上少于  中提供的选项数。

 

P

 

DESCRIPTION

共享内存是最快的可用IPC形式。它允许多个不相关(无亲缘关系)的进程去访问同一部分逻辑内存。

要注意的是共享内存本身没有提供任何同步功能。也就是说,在第一个进程结束对共享内存的写操作之前,并没有什么自动功能能够预防第二个进程开始对它进行读操作。共享内存的访问同步问题必须由程序员负责。可选的同步方式有互斥锁、条件变量、读写锁、纪录锁、信号灯。

实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止。

 

POSIX Shared Memory API

使用POSIX共享内存需要用到下面这些API:

#include <sys/types.h>
#include <sys/stat.h>        /* For mode constants */
#include <sys/mman.h>
#include <fcntl.h>           /* For O_* constants */
#include <unistd.h>

int shm_open(const char *name, int oflag, mode_t mode);
int shm_unlink(const char *name);
int ftruncate(int fildes, off_t length);
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
int munmap(void *addr, size_t len);
int close(int fildes);
int fstat(int fildes, struct stat *buf);
int fchown(int fildes, uid_t owner, gid_t group);
int fchmod(int fildes, mode_t mode);

shm_open

穿件并打开一个新的共享内存对象或者打开一个既存的共享内存对象, 与函数open的用法是类似的. 函数返回值是一个文件描述符,会被下面的API使用.

ftruncate

设置共享内存对象的大小,新创建的共享内存对象大小为0.

mmap

munmap

shm_unlink

删除一个共享内存对象名字.

close

当shm_open函数返回的文件描述符不再使用时,使用close函数关闭它.

fstat

获得共享内存对象属性的stat结构体. 结构体中会包含共享内存对象的大小(st_size), 权限(st_mode), 所有者(st_uid), 归属组 (st_gid).

fchown

改变一个共享内存对象的所有权.

fchmod

改变一个共享内存对象的权限.

 

Persistence(持续性)

POSIX 共享内存随内核持续: 共享内存对象会一直存在,直到系统关闭 或者 一个进程取消内存映射(unmapped)并且调用shm_unlink来删除共享内存对象.

Linking(链接库)

必须链接rt(librt)库,也就是real-time library.

-lrt

 

Accessing shared memory objects via the file system

Linux从内核2.4 和glibc 2.2版本开始支持POSIX共享内存.

 

从Linux内核2.6.19版本起, Linux支持使用访问控制列表(ACLs) 来控制虚拟文件系统中对象的权限.

 

Inherit

to be continued...

 

CONFORMING TO(遵守的彼岸准)

POSIX.1-2001.

 

NOTES

多进程必须使用同步机制来访问共享内存对象, 比如使用POSIX信号量.

System V 的共享内存是过时的, POSIX共享内存提供了使用更简单、设计更合理的API.

 

转载于:https://www.cnblogs.com/klb561/p/9286314.html

因篇幅问题不能全部显示,请点此查看更多更全内容

Top