- 浏览: 141075 次
文章分类
最新评论
在XSI IPC通信之消息队列和XSI IPC通信之信号量两节中,我们讨论了消息队列和信号量,这一节将继续讨论同属于 XSI IPC 的存储共享。
共享存储允许多个进程共享一个给定的存储区。因为数据不需要在进程之间复制,所以这是一种较快的 IPC。要注意的是,当一个进程在修改共享存储区时,其他进程不应该去操作这块区域。通常使用信号量来同步共享存储访问(当然也可使用记录锁或互斥量)。
mmap 就是共享存储的一种形式,它是将同一个文件映射到各个进程的地址空间。XSI 共享存储和内存映射的文件的区别是,前者没有相关的文件。XSI 共享存储段是内存的匿名段。
下表给出了影响共享存储的系统限制。
内核为每个共享存储段维护着一个结构,它至少包含下面这些成员。
其中的 ipc_perm 结构见XSI IPC 相似特征介绍。shmatt_t 类型定义为无符号整型,它至少与 unsigned short 一样大。
shmget 函数可以创建或获得一个共享存储标识符。shmctl 函数可对共享存储段执行多种操作。shmat 函数可将创建好的共享存储段连接到进程的地址空间中。shmdt 函数可将共享段与进程分离。
shmget 函数在创建一个新段时,会初始化 shmid_ds 结构的下列成员。
* ipc_perm 结构按XSI IPC 相似特征介绍一节中的所述进行初始化。该结构中的 mode 按 flag 中的相应权限位设置。
* shm_lpid、shm_nattach、shm_atime 和 shm_dtime 都设置为 0。
* shm_ctime 设置为当前时间。
* shm_segsz 设置为请求的 size。
参数 size 是共享存储段的长度,以字节为单位,通常将其向上取为系统页长的整数倍。若应用指定的 size 值并非系统页长的整倍数,则最后一页的余下部分是不可使用的。如果是在引用一个现存的段,则可将 size 指定为 0。创建一个新段时,段内的内容会被初始化为 0。
shmctl 函数的 cmd 参数可指定下列 5 种命令中的一种,使其在 shmid 指定的段上执行。
* IPC_STAT:取此段的 shmid_ds 结构,并将其存放在 buf 指向的结构中。
* IPC_SET:将字段 shm_perm.uid、shm_perm.gid、shm_perm.mode 从 buf 指向的结构复制到此队列关联的 shmid_ds 结构中。此命令只能由下列两种进程执行:一种是其有效用户 ID 等于 shm_perm.cuid 或 shm_perm.uid,另一种是具有超级用户特权的进程。
* IPC_RMID:从系统中删除该共享存储段。因为每个共享存储段维护着一个连接计数(及 shm_nattch字段),所以除非使用该段的最后一个进程终止或与该段分离,否则不会实际上删除该存储段。不过不管此段是否仍在使用,该段标识符都会被立即删除,不能再用 shmat 与该段连接。该命令也只能由上面提及的两种进程执行。
Linux 和 Solaris 还提供了如下的另外两种命令。
* SHM_LOCK:在内存中对共享存储段加锁。只能由超级用户执行。
* SHM_UNLOCK:解锁共享存储段。也只能由超级用户执行。
共享存储段连接到调用进程的哪个地址上与 shmat 函数的 addr 参数以及 flag 中是否指定了 SHM_RND 位有关,有以下几种情况。
(1)如果 addr 为 0,则此段连接到由内核选择的第一个可用地址上(推荐)。
(2)如果 addr 非 0,并且没有指定 SHM_RND,则此段连接到 addr 所指定的地址上。
(3)如果 addr 非 0,并且指定了 SHM_RND,则此段连接到(addr - (addr mod SHMLBA))所表示的地址上。SHM_RND 命令的意思是“取整”,SHMLBA 的意思是“低边界地址倍数”,它总是 2 的乘方,该算式是将地址向下取最近 1 个 SHMLBA 的倍数。
如果在 flag 中指定了 SHM_RDONLY 位,则以只读方式连接此段,否则以读写方式连接。
shmat 的返回值是该段所连接的实际地址,如果出错则返回 -1。如果 shmat 成功执行,那么内核将使相应 shmid_ds 结构中的 shm_nattch 计数器值加一。
当对共享存储段的操作已经结束时,就可调用 shmdt 函数与该段分离。不过这并不从系统中删除其标识符以及相关的数据结构,该标识符仍然存在,直至某个进程调用带 IPC_RMID 命令的 shmctl 函数来特地删除它为止。其中的 addr 参数是之前调用 shmat 时的返回值。如果成功,shmdt 将使相关 shmid_ds 结构中的 shm_nattch 计数器减一。
下面这个实例演示了将 addr 参数设为 0 的 shmat 函数的用法,它打印了一些特定系统存放各种类型的数据的位置信息(这些信息的说明见C 存储及环境一节)。
在一个基于 Intel 的 64 位 Linux 系统上运行此程序的结果如下:
下图显示了这种存储区布局示意图。
共享存储允许多个进程共享一个给定的存储区。因为数据不需要在进程之间复制,所以这是一种较快的 IPC。要注意的是,当一个进程在修改共享存储区时,其他进程不应该去操作这块区域。通常使用信号量来同步共享存储访问(当然也可使用记录锁或互斥量)。
mmap 就是共享存储的一种形式,它是将同一个文件映射到各个进程的地址空间。XSI 共享存储和内存映射的文件的区别是,前者没有相关的文件。XSI 共享存储段是内存的匿名段。
下表给出了影响共享存储的系统限制。
内核为每个共享存储段维护着一个结构,它至少包含下面这些成员。
struct shmid_ds{ struct ipc_perm shm_perm; size_t shm_segsz; // size of segment in bytes pid_t shm_lpid; // pid of last shmop() pid_t shm_cpid; // pid of creator shmatt_t shm_nattch; // number of current attaches time_t shm_atime; // last-attach time time_t shm_dtime; // last-detach time time_t shm_ctime; // last-change time /* ... */ };
其中的 ipc_perm 结构见XSI IPC 相似特征介绍。shmatt_t 类型定义为无符号整型,它至少与 unsigned short 一样大。
shmget 函数可以创建或获得一个共享存储标识符。shmctl 函数可对共享存储段执行多种操作。shmat 函数可将创建好的共享存储段连接到进程的地址空间中。shmdt 函数可将共享段与进程分离。
#include <sys/shm.h> int shmget(key_t key, size_t size, int flag); /* 返回值:若成功,返回共享存储 ID;否则,返回 -1 */ int shmctl(int shmid, int cmd, struct shmid_ds *buf); /* 返回值:若成功,返回 0;否则,返回 -1 */ void *shmat(int shmid, const void *addr, int flag); /* 返回值:若成功,返回指向共享存储段的指针;否则,返回 -1 */ int shmdt(const void *addr); /* 返回值:若成功,返回 0;否则,返回 -1 */
shmget 函数在创建一个新段时,会初始化 shmid_ds 结构的下列成员。
* ipc_perm 结构按XSI IPC 相似特征介绍一节中的所述进行初始化。该结构中的 mode 按 flag 中的相应权限位设置。
* shm_lpid、shm_nattach、shm_atime 和 shm_dtime 都设置为 0。
* shm_ctime 设置为当前时间。
* shm_segsz 设置为请求的 size。
参数 size 是共享存储段的长度,以字节为单位,通常将其向上取为系统页长的整数倍。若应用指定的 size 值并非系统页长的整倍数,则最后一页的余下部分是不可使用的。如果是在引用一个现存的段,则可将 size 指定为 0。创建一个新段时,段内的内容会被初始化为 0。
shmctl 函数的 cmd 参数可指定下列 5 种命令中的一种,使其在 shmid 指定的段上执行。
* IPC_STAT:取此段的 shmid_ds 结构,并将其存放在 buf 指向的结构中。
* IPC_SET:将字段 shm_perm.uid、shm_perm.gid、shm_perm.mode 从 buf 指向的结构复制到此队列关联的 shmid_ds 结构中。此命令只能由下列两种进程执行:一种是其有效用户 ID 等于 shm_perm.cuid 或 shm_perm.uid,另一种是具有超级用户特权的进程。
* IPC_RMID:从系统中删除该共享存储段。因为每个共享存储段维护着一个连接计数(及 shm_nattch字段),所以除非使用该段的最后一个进程终止或与该段分离,否则不会实际上删除该存储段。不过不管此段是否仍在使用,该段标识符都会被立即删除,不能再用 shmat 与该段连接。该命令也只能由上面提及的两种进程执行。
Linux 和 Solaris 还提供了如下的另外两种命令。
* SHM_LOCK:在内存中对共享存储段加锁。只能由超级用户执行。
* SHM_UNLOCK:解锁共享存储段。也只能由超级用户执行。
共享存储段连接到调用进程的哪个地址上与 shmat 函数的 addr 参数以及 flag 中是否指定了 SHM_RND 位有关,有以下几种情况。
(1)如果 addr 为 0,则此段连接到由内核选择的第一个可用地址上(推荐)。
(2)如果 addr 非 0,并且没有指定 SHM_RND,则此段连接到 addr 所指定的地址上。
(3)如果 addr 非 0,并且指定了 SHM_RND,则此段连接到(addr - (addr mod SHMLBA))所表示的地址上。SHM_RND 命令的意思是“取整”,SHMLBA 的意思是“低边界地址倍数”,它总是 2 的乘方,该算式是将地址向下取最近 1 个 SHMLBA 的倍数。
如果在 flag 中指定了 SHM_RDONLY 位,则以只读方式连接此段,否则以读写方式连接。
shmat 的返回值是该段所连接的实际地址,如果出错则返回 -1。如果 shmat 成功执行,那么内核将使相应 shmid_ds 结构中的 shm_nattch 计数器值加一。
当对共享存储段的操作已经结束时,就可调用 shmdt 函数与该段分离。不过这并不从系统中删除其标识符以及相关的数据结构,该标识符仍然存在,直至某个进程调用带 IPC_RMID 命令的 shmctl 函数来特地删除它为止。其中的 addr 参数是之前调用 shmat 时的返回值。如果成功,shmdt 将使相关 shmid_ds 结构中的 shm_nattch 计数器减一。
下面这个实例演示了将 addr 参数设为 0 的 shmat 函数的用法,它打印了一些特定系统存放各种类型的数据的位置信息(这些信息的说明见C 存储及环境一节)。
#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #define ARRAY_SIZE 40000 #define MALLOC_SIZE 100000 #define SHM_SIZE 100000 #define SHM_MODE 0600 // user read/write char array[ARRAY_SIZE]; // uninitialized data = bss int main(void){ int shmid; char *ptr, *shmptr; printf("array[] from %p to %p\n", &array[0], &array[ARRAY_SIZE]); printf("stack around %p\n", &shmid); if((ptr=malloc(MALLOC_SIZE)) == NULL){ printf("malloc error\n"); exit(1); } printf("malloced from %p to %p\n", ptr, ptr+MALLOC_SIZE); shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE); if((shmptr=shmat(shmid, 0, 0)) != (void *)-1){ printf("shared memory attached from %p to %p\n", shmptr, shmptr+SHM_SIZE); shmctl(shmid, IPC_RMID, 0); } exit(0); }
在一个基于 Intel 的 64 位 Linux 系统上运行此程序的结果如下:
$ ./prtMemoryLayout.out array[] from 0x6020c0 to 0x60bd00 stack around 0x7fff957b146c malloced from 0x9e3010 to 0x9fb6b0 shared memory attached from 0x7fba578ab000 to 0x7fba578c36a0
下图显示了这种存储区布局示意图。
发表评论
-
打开伪终端设备
2018-07-09 20:50 1249在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1535伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 792多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 944终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 566尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 935虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 707tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 810终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 433终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 575在XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 612在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 490消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 481有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 413FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 383管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 879readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 451POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 588记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 433UNIX 系统中,守护进程遵循下列通用惯例。 ... -
守护进程编写规则与出错记录
2017-12-26 01:53 450在编写守护进程程 ...
相关推荐
Linux中的XSI IPC(System V Interprocess Communication)是系统V接口的一种实现,它提供了一种在不同进程间共享数据的方法。XSI IPC包括了三种主要机制:消息队列、信号量和共享内存。这些机制允许进程之间进行...
其中,信号量结合共享存储区(ShareMemory)和消息传递统称为XSI IPC(扩展系统接口进程间通信),提供了一种高效的进程间通信机制。 #### 共享存储与信号量:一种高效IPC方案 文章进一步探讨了信号量与共享存储区...
Liferay IPC机制使得不同的portlet能够共享数据和事件,增强了portlet之间的协作能力。这种通信方式分为两种主要类型:异步(Asynchronous)和同步(Synchronous)。异步通信通常用于不阻塞用户界面的背景任务,而...
【XSI融和球插件】是一款专为Softimage XSI(现在称为SILVERGUN)设计的强大特效工具,其在3D动画和视觉效果领域具有广泛的应用。这款插件以其独特的“融合球”技术著称,允许艺术家创建出高度复杂的形状和动态效果...
T-Gen是第一个完全整合进XSI的植物生成插件。超过100种造型和分布的参数,与XSI的曲线和基于节点的体系完美配合确保了用户创造自定性的植物时拥有强大的灵活性和无穷的可能性。你可以使用几乎所有的XSI工具对T-Gen...
XSI经典插件emFluid3破解版XSI经典插件emFluid3破解版XSI经典插件emFluid3破解版XSI经典插件emFluid3破解版
"XML中的xmlns、xmlns:xsi和xsi:schemaLocation详解" XML文档中的xmlns、xmlns:xsi和xsi:schemaLocation是三个重要的元素,分别用于定义XML文档的命名空间、XML schema实例和schemaLocation。 一、xmlns xmlns是...
字符串是 Python 中最基本的数据类型之一,用于存储文本信息。在 XSI 脚本中,字符串常用来处理文件路径、对象名称等。 **2.2.2 数字** Python 支持多种数字类型,包括整数、浮点数和复数等。这些数据类型在处理...
标题中的"SPH.rar_SPH_SPH XSI_xsi sph plugin"揭示了这是一个与流体模拟相关的软件插件,主要用于3D建模和动画软件Softimage XSI(也称为XSI)。SPH代表Smoothed Particle Hydrodynamics(平滑粒子流体动力学),这...
Autodesk SoftImage 2013 的破解工具。 你懂的
keygen downloader for xsi 2011 x 64. The way to finder keygen
XSI 7 的破解方法,图片视图,很直观,请多多支持,谢谢!!!
Softimage|XSI2012注册机 x32 x64 艺术挑战技术,技术启发艺术
另外普通的mutex是作用线程间同步用的,但是可以将进程A和进程B共享的内存中初始化一个mutex,这样就可以用将此mutex用作进程间通信用了。 扩展 进程与内核通信 其实本来的计划是分两个大块,一块写进程间通信,一块...
UWB技术的标准制定过程中出现了Intel与TI为代表的MBOA提案和以摩托罗拉与XSI为代表的DS-CDMA提案两大阵营。虽然无线电制造商PulseLink提出了一种允许不同UWB系统共存的公共信号协议(CSP),但仍面临标准统一的问题...
2. 配置Redis服务器,用于存储Session数据。 3. 在应用程序中使用Spring Session代替传统的HTTPSession。 4. 使用Nginx或其他反向代理服务器来管理多个实例,并将请求分发到不同的实例上。 结论 Springboot实现...
为了创建这样一个空节点,可以使用`XmlDocument`类创建一个新元素,并添加`xsi:nil`属性设置为`"true"`。代码示例如下: ```csharp public static XmlElement CreateNodeWithNullAttr(XmlDocument doc, string ...