cit*_*kid 7 mmap memory-mapped-files memory-mapping node.js
node.js存在mmap模块:https://github.com/bnoordhuis/node-mmap/
正如作者Ben Noordhuis指出的那样,访问映射内存可能会阻塞,这就是为什么他不再推荐它并停止使用它.
所以我想知道如何为node.js设计一个非阻塞内存映射模块?线程,纤维,?
显然,如果node.js中的线程只发生在其他地方而不是请求处理程序,那么这附近会引发一个问题.
jos*_*736 12
当谈论以非阻塞方式实现一些本地设施时,首先要看的是libuv.这是节点的核心模块与底层平台的接口.特别感兴趣的是工作队列 API.
如果我们快速查看node-mmap的源代码,我们会发现它实际上非常简单.它调用mmap并返回一个Buffer包装映射内存区域的节点.
从中读取Buffer是导致操作系统执行I/O的原因.因为这必然会在JS线程上发生,我们最终会阻止带有磁盘I/O的JS线程.
Buffer您应该在C++中编写一个包装类,通过工作队列进行读写操作,而不是返回允许JS直接访问映射内存的方法.这样,磁盘I/O将在单独的线程上发生.
在JS中,你会使用类似这样的东西:
fs.open('/path/to/file', 'r', function(err, fd) {
fs.fstat(fd, function(err, stats) {
var mapped = mmap.map(stats.size, mmap.PROT_READ, mmap.MAP_SHARED, fd, 0);
mapped.read(start, len, function(err, data) {
// ...
});
});
});
Run Code Online (Sandbox Code Playgroud)
在C中,该read函数将创建一个libuv工作请求并将其排入工作队列.然后,C worker函数将读取映射的内存范围(基于调用者的规范),这可能会导致磁盘I/O,但这是安全的,因为它发生在一个单独的线程上.
接下来发生的事情很有趣.安全的方法是为工作者alloc提供新的内存块和memcpy映射的内存.然后工作者将指针传递给副本,然后C回调将其包装在一个Buffer要返回给JS-land的地方.
您还可以尝试读取范围(以便在工作线程上发生任何必要的I/O)但实际上没有对数据执行任何操作,然后使用C回调只是将映射的内存范围包装在a中Buffer.从理论上讲,工作者读取的文件部分将保留在RAM中,因此访问映射内存的那部分不会阻塞.但是,老实说我对映射内存知之甚少,不知道这是否会最终让你感到困惑.
最后,我怀疑这是否会在节点的常规fs方法上提供任何额外的性能.如果我做的事情非常合理,mmap我只会走这条路.
| 归档时间: |
|
| 查看次数: |
4156 次 |
| 最近记录: |