NetBSD进程间通讯系统分析

简单的进程间通讯: 管道

管道是 UNIX 最传统, 最简单, 也是最有效的进程间通讯方法. NetBSD 处理管道的代码在 kern/sys_pipe.c, 它的读写函数作为 file 结构的 fileops 挂载, 并在 read(2), write(2) 时被调用.

管道创建

pipe(2) 的响应函数实 sys_pipe(). 它首先两次调用 pipe_create(), 第一次申请读端口将调用 pipespace() 申请一个用作缓冲区的内核地址空间 (回忆 BsdSrcUvm, submap); 第二次申请写端口则不申请空间. 这样, 我们就得到了两个 pipe 结构, 对应管道的两个端口. 把缓冲区放到 rpipe 是有道理的, 因为这样即使写端口关闭了我们还可以把剩余数据读出, 而如果读端口 (消费者) 关闭了, 写端口 (生产者) 写数据也没有意义了.

接下来 sys_pipe() 的工作就是让两个端口相连和使它们与文件接口相连. 我们分别申请读写两段对应的 file 结构, 填写返回值; 然后设置 pipe_peer 将 pipe 的两个端口相连. 所有的工作就完成了.

管道读

管道读的响应函数为 pipe_read(). 我们进入了一个常见的循环, 如果请求读的字节还没完成, 我们就继续在缓冲区取数据 (XXX. 忽略 NODIRECT 的情况, 我们得先保证我们的叙述能构建一个 可运行 的系统); 否则, 假如我们没收到文件结束讯号, 又在阻塞读状态, 我们就得等待, 等待前我们还得先唤醒控制得 select/poll 函数或者生产者 writer, 否则我们的等待是永远不会结束的.

管道写

我们再来看管道写的 pipe_write() 函数. 我们首先注意到一个比较郁闷的 rpipe 和 wpipe 的指称. 这时候的 wpipe 所指向的, 其实是 pipe(2) 创建的 rpipe, 因为我们要把数据 写到读端口让它来读. 我们还可以根据要写入的数据大小判断当前 pipe 的 buffer 是否够大, 可以随时扩充之.

我们又进入了一个与 pipe_read() 相似的循环. (XXX. NODIRECT) 接下来的处理过程也是相似的, 注意 space 的计算, 我们倾向于一次性把数据写入, 如果不行, 我们宁愿先等待.

管道关闭

pipe_close() 只需应付一下文件接口, 将 f_data 清空, 真正的 pipe 关闭工作由 pipeclose() 完成. 在这里, 我们主要要修改对端状态, 告诉它我们要死了, pipe 结束了, 把对端指向自己的 pipe_peer 域清空. 然后对因读或写等待的对端, 唤醒之, 让它处理这个事件. 接着, 我们返还所有资源: 缓冲区(如果是读端口), pipe 结构, 这个端口的生命就结束了.

BSD 进程间通讯: socket

请参考 BsdSrcSocket

SystemV IPC

SystemV IPC 是由商业发行 SystemV UNIX 带来的通信机制. 它包括消息, 共享存储区, 信号量, 实现了良好的本地进程通信接口. 在 NetBSD 中实现的代码在 kern/sysv_*.

对象标识

作为进程间通讯单位并允许多个进程 (而非 pipe 的两个进程点对点) 通讯, 其通讯单位显然是系统的且全局的. 三种通信机制的对象都有相同的标识方法: 每种机制都包含一个表, 其中的表项描述该机制的所有实例; 每个表项都有一个用户选定的 key, 各个进程可以通过 key 获取通信对象实例, 从而互相通信. 每个通信对象实例又对应一个全局唯一的标识符, 以进行真正的通信.

考虑这个全局标识符就是对象实例再表中的位置, 我们将面临一种情况, 某个程序使用一个 id 做通讯, 可是这个 id 所对应的通信实例可能已被撤消, 这个位置又换上了另一个通信实体, 而这个程序对此一无所知, 继续操作, 这会造成灾难性后果. 我们的解决方法是加上一个 _seq 域, 每次申请一个实例, 就将其 _seq 域加 1, 我们返回的标识符为 _seq * 65536 + 实例在表中的位置, 这样就不会产生这种混乱了.

每个 IPC 结构都有一个权限表项, 其权限设置与文件的权限设置相似, 通过它我们可以限定某些进程相互通信的权限.

以上标识方法的描述在 struct ipc_perm, 每个 IPC 对象结构都带有一个 ipc_perm.

消息队列 (message queue)

消息的对象结构描述在 struct msqid_ds, 全局的控制结构在 struct msginfo.

时间: 2024-12-01 18:46:49

NetBSD进程间通讯系统分析的相关文章

PHP中实现进程间通讯

进程 PHP中实现进程间通讯 邱文宇   本文将讨论在PHP4环境下如何使用进程间通讯机制--IPC(Inter-Process-Communication).本文讨论的软件环境是linux+php4.0.4或更高版本.首先,我们假设你已经装好了PHP4和UNIX, 为了使得php4可以使用共享内存和信号量,必须在编译php4程序时激活shmop和sysvsem这两个扩展模块. 实现方法:在PHP设定(configure)时加入如下选项. --enable-shmop --enable-sysv

在PHP中实现进程间通讯

本文将讨论在PHP4环境下如何使用进程间通讯机制--IPC(Inter-Process-Communication).本文讨论的软件环境是linux+php4.0.4或更高版本.首先,我们假设你已经装好了PHP4和UNIX, 为了使得php4可以使用共享内存和信号量,必须在编译php4程序时激活shmop和sysvsem这两个扩展模块. 实现方法:在PHP设定(configure)时加入如下选项. --enable-shmop --enable-sysvsem  这样就使得你的PHP系统可以处理

Linux 进程间通讯共享内存方式

共享内存方式:从物理内存里面拿出来一部分作为多个进程共享. 共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入数据,共享这个内存的所有进程都可以立即看到其中内容. 共享内存实现步骤: 一.创建共享内存,使用shmget函数. 二.映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数. 创建共享内存shmget: intshmget(key_t key, size_t size, int shmflg) 功能:得到一个共享内存标识符或创建一个共享内存对象并

c++进程间通讯(共享内存)时

问题描述 c++进程间通讯(共享内存)时 我的需求:一个进程批量的数据不间断的存入差不多每秒有400k的数据这样子(不一定是一次存入的,可能是分几次),而另一个内存要从共享内存中读取这些数据,读取完就释放那块内存. 如何使共享的内存具有一定的数据结构,如同stl中的vector那样. 解决方案 需要自己做序列化,反序列化,把数据转回vector.自己定义格式等,知道多大一块内存数据表示一个vector的元素.然后一个个获取,存入vector 解决方案二: 如何使共享的内存具有一定的数据结构?共享

关于linux使用动态库进行进程间通讯

问题描述 关于linux使用动态库进行进程间通讯 各位: 两个进程间通过动态库的方式如何进行参数的传递? 我首先在一个库中做了如下的内容: #include ""caculate.h""#include ""stdio.h""int iShare; #pragma data_seg (""shareddate"")int iShareInSeg = 1;#pragma data_seg#

进程间通讯-Android开发 AIDL接口文件里使用内部类报错unknown type

问题描述 Android开发 AIDL接口文件里使用内部类报错unknown type 在Android开发时涉及到一个进程间通讯,要传递一个内部类对象到远程服务端.已经把内部类对象用Parcelable序列化了,但是编译总是报错unknown type 外部类.内部类. 1.AIDL能否传递内部类对象到远程端? 2.此问题该怎样解决?

C#进程间通讯技术-整理。

原文:C#进程间通讯技术-整理.   扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html   一.进程间通讯的方式 1)共享内存 包括:内存映射文件,共享内存DLL,剪切板. 2)命名管道及匿名管道 3)消息通讯 4)利用代理方法.例如SOCKET,配置文件,注册表方式. 等方式. 方法一:通讯. 进程间通讯的方式有很多,常用的有共享内存(内存映射文件.共享内存DLL.剪切板等).命名管道和匿名管道.发送消息

PHP中实现进程间通讯_php基础

PHP中实现进程间通讯 邱文宇   本文将讨论在PHP4环境下如何使用进程间通讯机制--IPC(Inter-Process-Communication).本文讨论的软件环境是linux+php4.0.4或更高版本.首先,我们假设你已经装好了PHP4和UNIX, 为了使得php4可以使用共享内存和信号量,必须在编译php4程序时激活shmop和sysvsem这两个扩展模块. 实现方法:在PHP设定(configure)时加入如下选项. --enable-shmop --enable-sysvsem

进程间通讯问题,内存共享的实现

问题描述 需要在多个进程传输数据,其实一个检测进程一直获取检测的数据,供其他进程及时读取使用,数据库不是很大,但是数据更新非常的频繁,考虑到效率问题,不知道用什么方法实现?暂时决定采用内存共享的方式实现.希望各位大虾多加指点.具体怎么实现比较好?需要注意哪些地方?如果有类似的源代码参考就最好了. 解决方案 解决方案二:方案1.使用WM_COPYDATA消息方案2.使用WriteProcessMemory(),ReadProcessMemory()访问其他进程的内存方案3.使用内存镜像文件解决方案