.pipe()是否在node.js中执行memcpy?

这是关于系统级优化的概念性查询。 通过阅读NodeJS文档,我的理解是pipe道很方便地在stream上执行stream量控制。

背景:我有麦克风stream,我想避免额外的复制操作,以节省整体系统MIPS。 据我所知,对于audiostream,即使有一个memcopy,但是我并没有花费大量的MIPS,但是我也有一个扩展计划,以30fps和UHD分辨率在相机帧中进行stream式处理。 以30fps制作UHD分辨率像素数据的多个副本是非常低效的,所以需要一些build议。

示例代码:

var spawn = require('child_process').spawn var PassThrough = require('stream').PassThrough; var ps = null; //var audioStream = new PassThrough; //var infoStream = new PassThrough; var start = function() { if(ps == null) { ps = spawn('rec', ['-b', 16, '--endian', 'little', '-c', 1, '-r', 16000, '-e', 'signed-integer', '-t', 'raw', '-']); //ps.stdout.pipe(audioStream); //ps.stderr.pipe(infoStream); exports.audioStream = ps.stdout; exports.infoStream = ps.stderr; } }; var stop = function() { if(ps) { ps.kill(); ps = null; } }; //exports.audioStream = audioStream; //exports.infoStream = infoStream; exports.startCapture = start; exports.stopCapture = stop; 

以下是问题:

  1. 为了能够执行stream量控制,source.pipe(dest)是否从源内存执行memcpy到目标内存,或者是否将内存中的引用传递到目标?
  2. 评论的代码包含一个PassThrough类实例化 – 我目前假设PassThrough也会导致memcopies,所以我在整个系统中保存一个memcpy操作,因为我在上面的注释中添加了?
  3. 如果我必须在Process和Spawned Child进程之间创build一个pipe道(使用child_process.spawn(),如在不使用阻塞stdio的情况下如何在node.js中将大数据从/传输到subprocess )假定肯定会导致memcpy? 无论如何,这是一个参考,而不是复制?
  4. 这种行为不同于操作系统到操作系统? 我认为它应该是操作系统不可知论的,但反过来问这个。

在此先感谢您的帮助。 这将有助于我的build筑很多。

有些url可供参考: https : //github.com/nodejs/node/
https://github.com/nodejs/node/blob/master/src/stream_wrap.cc
https://github.com/nodejs/node/blob/master/src/stream_base.cc
https://github.com/libuv/libuv/blob/v1.x/src/unix/stream.c
https://github.com/libuv/libuv/blob/v1.x/src/win/stream.c

我试图写一个复杂的/巨大的解释,基于这些和其他一些文件,但是我得出的结论是最好给你一个我的经验/阅读如何告诉我节点内部工作的总结:

pipe道只是连接stream,使得它看起来好像.on("data", …).write(…)调用,没有任何臃肿之间。

现在我们需要将js世界从c ++ / c世界中分离出来。
当处理js中的数据时,我们使用缓冲区。 https://github.com/nodejs/node/blob/master/src/node_buffer.cc
他们只是代表分配的内存与顶部的一些糖果来操作。

如果你将一个进程的标准输出连接到一些.on("data", …)监听器,它将把传入的块复制到一个Buffer对象中,以便在js世界中进一步使用。
在js世界里,你有像.pause()等方法(你可以在节点的steam api文档中看到)来防止进程吃掉内存,以防input数据比其处理速度快。

连接一个进程的标准输出和例如一个通过pipe道输出的TCP端口将会产生类似于nginx操作的连接。 它将连接这些数据stream,就好像它们直接将传入的数据复制到外部数据stream中一样。

一旦你暂停一个stream,节点将使用内部缓冲,以防止它无法暂停传入的stream。

所以对于你的情况,你应该做testing。
尝试通过节点中的传入stream接收数据,暂停stream,看看会发生什么。
我不确定节点是否会使用内部缓冲,或者如果您尝试运行的进程只是暂停,直到它可以继续发送数据。
我期望过程停止,直到你继续stream。

为了传输巨大的图像,我build议将它们分块传输,或者直接将它们传输到一个传出端口。

块的方式将允许您一次发送数据到多个客户端,并将保持内存占用相当低。

PS你应该看看这个我刚刚发现的要点: https : //gist.github.com/joyrexus/10026630
它深入解释了如何与stream进行交互