|
STREAM I/O 子系统 (不要和标准 I/O 库使用的文件流混淆)提供了一个框架,用于将设备驱动程序连接到内核中。
基本的 STREAM 单位是流。流(stream),是进程和 STREAMS 设备驱动程序之间的全双工数据路径。当进程打开 STREAMS 时创建的流包含 3 个部分:流头、零个或多个模块,以及驱动程序。当第一次打开 STREAMS 设备时,流只包含流头和驱动程序。
流头 (stream head)
是最接近于用户进程的流一端,并且是流和进程之间的接口。当进程建立具有 STREAMS 文件描述符的系统调用时,调用流头例程,从而导致执行数据复制、消息生成或控制操作。流头是流中能够在进程和内核之间复制数据的唯一部分。
STREAMS 模块 (STREAMS module)
是一组内核驻留的函数和数据结构,用于处理通过它的数据。通过使用 ioctl 将模块推入到流上。之所以说将模块推入到流上,是因为插入的新模块就在流头的下面,同时向下推任何其他的模块。通过使用另一个 ioctl ,可以将顶部的模块 (直接在流头下面) 从流中弹出。
STREAMS 驱动程序 (STREAMS driver)
是最远离用户进程的流的一端,在流头和可能已经推入到流上的任何模块的下面。驱动程序可以和外部设备连接,或者它可以是伪设备的驱动程序,伪设备是只存在于软件中的内部设备。
通过沿着队列传递消息,在 STREAMS 中执行所有 I/O (严格来说,它是指向沿着队列传递的消息的指针,用于避免数据复制带来的昂贵开销)。每个流头,模块和驱动程序有两个队列:读队列和写队列。
当消息从一个模块的读队列传递到下一个模块的读队列时,可以说成是传播上行数据流。相反,将消息从一个模块的写队列传递到下一个模块的写队列时可以说成是传播下行数据流。还句话说,写入到流头的数据传播下行数据流,而从设备读取的数据传播上行数据流。原理图如下所示:
![]()
上图中,流头和 STREAMS 模块之间 (以及从模块到驱动程序)的箭头代表消息队列。STREAMS 模块是可选的,即可能有多个模块被推到流上。
与流进行交互,方法是使用 open() , close(), read(), write() , poll() 以及 ioctl() 等函数。针对流打开的路径名通常位于 /dev 中或它的一个子目录中,但没有任何方法在只有使用 ls 的情况下确定文件是否是 STREAMS 设备。但是,所有的 STREAMS 设备都是字符特殊文件。
可以使用 isastream 函数来确定文件描述符是否表示 STREAMS 设备,关于 isastream 函数见:
http://www.groad.net/bbs/read.php?tid-1254.html |
|