Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Buffer 被写入 Stream 并没有 copy

  把一个 Buffer 对象写入到 Stream 中到底是怎么处理的?昨天在写要给 socket 的测试 demo 时发现了一件奇怪的事情。我疯狂地往 socket 写入 1GB 大小的 Buffer,进程的内存并没有爆炸。于是才察觉到,把 Buffer 写入 Stream 中这个动作只是传入一个指针而已,并没有复制内存。
  下面这个就是那坨跑不挂的神奇代码:
let cluster = require('cluster'); let net = require('net'); if (cluster.isMaster) { cluster.fork(); net.createServer(socket => { void function callee() { let data = new Buffer(1024 * 1024 * 1024); let len = data.length.toLocaleString(); console.log('\x1b[1;32msend \x1b[1m' + len + ' bytes\x1b[0m'); socket.write(data); setTimeout(callee, 16); }(0); }).listen(3000); } else { let socket = net.connect(3000); socket.on('data', data => { let len = data.length.toLocaleString(); console.log('\x1b[1;35mrecv \x1b[1m' + len + ' bytes\x1b[0m'); for (let i = 0; i < 1E8; i++); }); }   代码中让 Worker 每次执行一个 1E8 次的空循环,模拟它卡住的情况。而主进程疯狂地 write 进巨大的 Buffer。
  我一直以为 Buffer 被写入 Stream 是一个 copy 的行为,没想到只是把指针推进去了。上面的程序之所以跑不挂是因为 Buffer 创建时并不会立即申请内存,只有在有写操作时才分配内存。而将 Buffer 写入 Stream 又只是推指针而已,所以从头到尾都没有处理到那个巨大的内存。
  那么问题来了,既然写入 Stream 只是推指针,那是不是就意味着即便 stream.write 调用时传入的数据是正确的,也不代表真正被读取到的就一定是这份数据?或许在 Buffer 被写入到 Stream 之后和真正被读取的这个间隙之间,Buffer 的内容可能被篡改?
网名:
54.161.8.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^