嘿嘿。
我正在使用 Node.JS
和 child_process
来生成 bash 进程。我试图了解我是否正在执行 I/O 绑定(bind)、CPU 绑定(bind)或两者兼而有之。
我正在使用 pdftotext提取 10k+ 文件的文本。为了控制并发,我使用 async .
代码:
let spawn = require('child_process').spawn;
let async = require('async');
let files = [
{
path: 'path_for_file'
...
},
...
];
let maxNumber = 5;
async.mapLimit(files, maxNumber, (file, callback) => {
let process = child_process.spawn('pdftotext', [
"-layout",
"-enc",
"UTF-8",
file.path,
"-"
]);
let result = '';
let error = '';
process.stdout.on('data', function(chunk) {
result += chunk.toString();
});
process.stderr.on('error', function(chunk) {
error += chunk.toString();
});
process.on('close', function(data) {
if (error) {
return callback(error, null);
}
callback(null, result);
});
}, function(error, files) {
if (error) {
throw new Error(error);
}
console.log(files);
});
我正在监控我的 Ubuntu 使用情况,当我运行程序时我的 CPU 和内存都非常高,而且有时我看到一次只处理一个文件,这正常吗??可能是什么问题??
我正在尝试理解 child_process 的概念。 pdftotext
是 Node.JS
的子进程吗?所有子进程都只在一个核心中运行?还有,我怎样才能让我的电脑更软处理这些文件?
glancer 的酷图:
Node.JS 的这种用法是因为 child_process 的吗??
谢谢。
最佳答案
如果您的作业需要 CPU,那么要运行的最佳作业数通常是内核数(如果 CPU 具有超线程,则为内核数的两倍)。因此,如果您有一台 4 核机器,您通常会通过并行运行 4 个作业来获得最佳速度。
但是,现代 CPU 严重依赖缓存。这使得很难预测并行运行的最佳作业数量。加上磁盘的延迟,这会使它变得更加困难。
我什至见过系统上的作业,其中内核共享 CPU 缓存,并且一次运行单个作业速度更快 - 仅仅是因为它可以使用完整的 CPU 缓存。
由于那次经历,我的建议一直是:衡量。
因此,如果您要运行 10k 个作业,请尝试并行运行 100 个不同数量的随机作业,看看最适合您的作业数。随机选择很重要,这样您还可以测量磁盘 I/O。如果文件大小差异很大,请运行几次测试。
find pdfdir -type f > files
mytest() {
shuf files | head -n 100 |
parallel -j $1 pdftotext -layout -enc UTF-8 {} - > out;
}
export -f mytest
# Test with 1..10 parallel jobs. Sort by JobRuntime.
seq 10 | parallel -j1 --joblog - mytest | sort -nk 4
不要担心您的 CPU 以 100% 的速度运行。这只是意味着您在电脑商店花的所有钱都能得到返回。
只有当磁盘缓存变低时,您的 RAM 才会成为问题(在您的屏幕截图中,754M 并不低。当它小于 100M 时,它就变低了),因为这可能会导致您的计算机开始交换 - 这可能会减慢它的速度抓取。
关于node.js - I/O 绑定(bind)和 CPU 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37945596/