文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何使用Node.js+COW技术进行进程创建和文件复制

2024-04-02 19:55

关注

如何使用Node.js+COW技术进行进程创建和文件复制,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

如何使用Node.js+COW技术进行进程创建和文件复制

COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。

一般来说复制就是创建出完全相同的两份,两份是独立的:

如何使用Node.js+COW技术进行进程创建和文件复制

但是,有的时候复制这件事没多大必要,完全可以复用之前的,这时候可以只是引用之前的那份,在写内容的时候才去复制对应的一部分内容。这样如果内容用于读的话,就免去了复制,而如果需要写,才会真正复制部分内容来做修改。

如何使用Node.js+COW技术进行进程创建和文件复制

这就叫做“写时复制”,也就是 Copy-On-Write。

原理很简单,但是在操作系统的内存管理和文件系统中却很常见,Node.js 里面也因为这种技术变“懒”了。

本文我们来探究下 Copy-On-Write 在 Node.js 的进程创建和文件复制的应用。【推荐学习:《nodejs 教程》】

文件复制

文件复制这件事最常见的思路就是完全写一份相同的文件内容到另一个位置,但是这样有两个问题:

怎么办呢?这时候操作系统设计者就想到了 COW 技术。

用 COW 技术实现文件复制以后完美解决了上面两个问题:

在 Node.js 的 fs.copyFile 的 api  就可以使用 Copy-On-Write 模式:

默认情况下,copyFile 会写入目标文件,覆盖原内容

const fsPromises = require('fs').promises;

(async function() {
  try {
    await fsPromises.copyFile('source.txt', 'destination.txt');
  } catch(e) {
    console.log(e.message);
  }
})();

但是可以通过第三个参数指定复制的策略:

const fs = require('fs');
const fsPromises = fs.promises;
const { COPYFILE_EXCL, COPYFILE_FICLONE, COPYFILE_FICLONE_FORCE} = fs.constants;

(async function() {
  try {
    await fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_FICLONE);
  } catch(e) {
    console.log(e.message);
  }
})();

支持的 flag 有 3 个:

这3个常量分别是 1,2,4,可以通过按位或把它们合并之后传入:

const flags = COPYFILE_FICLONE | COPYFILE_EXCL;
fsPromises.copyFile('source.txt', 'destination.txt', flags);

Node.js 支持操作系统的 copy-on-write 技术,在一些场景下可以提升性能,建议使用 COPYFILE_FICLONE 的方式,会比默认的方式好一些。

进程创建

fork 是常见的创建进程的方式,而它的实现就是一种 copy-on-write 技术。

我们知道,进程在内存中分为代码段、数据段、堆栈段这 3 部分:

如果基于该进程创建一个新的进程,那么要复制这 3 部分内存。而如果这三部分内存是一样的内容,那就浪费了内存空间。

所以 fork 并不会真正的复制内存,而是创建一个新的进程,引用父进程的内存,当做数据的修改的时候,才会真正复制该部分的内存。

如何使用Node.js+COW技术进行进程创建和文件复制

这也是为什么把进程创建叫做 fork,也就是分叉,因为不完全是独立的,只是某部分做了分叉,成了两份,但是大部分还是一样的。

但如果要执行的代码不一样怎么办呢,这时候就要用 exec 了,它会创建新的代码段、数据段、堆栈段、执行新的代码。

Node.js 里面同样可以用 fork 和 exec 的 api:

fork:

const cluster = require('cluster');

if (cluster.isMaster) {
  console.log('I am master');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log(`I am worker #${cluster.worker.id}`);
}

exec:

const { exec } = require('child_process');
exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

fork 是 linux 进程创建的基础,由此可见 copy-on-write 技术多么重要了。

复制同样的内容多份无疑比较浪费空间,所以操作系统在做文件复制、进程创建时的内存复制的时候都采用了 Copy-On-Write 技术,只有真正修改的时候才会去做复制。

Node.js 支持了 fs.copyFile 的 flags 的设置,可以指定 COPYFILE_FICLONE 来使用 Copy-On-Write 的方式做文件复制,也建议大家使用这种方式来节省硬盘空间,提高文件复制的性能。

进程的 fork 也是 Copy-On-Write 的实现,并不会直接复制进程的代码段、数据段、堆栈段到新的内容,而是引用之前的,只有在修改的时候才会做真正的内存复制。

除此以外,Copy-On-Write 在 Immutable 的实现,在分布式的读写分离等领域都有很多应用。

COW 让 Node.js 变“懒”了,但性能却更高了。

看完上述内容,你们掌握如何使用Node.js+COW技术进行进程创建和文件复制的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯