我需要运行一个函数int f(int i)
有 10_000 个参数,由于 I/O 时间的原因,执行大约需要 1 秒。
在像Python这样的语言中,我可以使用线程(或者async/await
,我知道,但是我稍后会谈到)来并行化这个任务。
如果我想始终有 10 个正在运行的线程,并在它们之间分配任务,我可以使用线程池 https://stackoverflow.com/questions/3033952/threading-pool-similar-to-the-multiprocessing-pool :
def f(p):
x = [...]
return x
p = ThreadPool()
xs = p.map(f, range(10_000))
But 它是如何工作的?如果我想用 NodeJS 和f = http("www.google.com", callback)
,我应该从哪里开始?解决这类问题的算法是什么?
同样,我想同时收到 10 个请求,当一个请求完成后,下一个请求应该开始。
到目前为止我一直在想什么(很难看,因为回调正在开始对 f() 函数的新调用):
queue = ["www.google.com", "www.facebook.com"]
var f = function(url) {
http.get(url, (e) => {
const newUrl = queue.pop();
f(newUrl);
});
};
for (var i = 0; i < 10; i++) {
f(queue.pop());
}
重新实现我链接到的 Bluebird 函数:
const mapWithConcurrency = async (values, concurrency, fn) => {
let i = 0;
let results = values.map(() => null);
const work = async () => {
while (i < values.length) {
const current = i++;
results[current] = await fn(values[current]);
}
};
await Promise.all(Array.from({length: concurrency}, work));
return results;
};
mapWithConcurrency(Array.from({length: 30 * 15}, (_, i) => i), 10, async i => {
const el = document.body.appendChild(document.createElement('i'));
el.style.left = 5 * (i % 30) + 'px';
el.style.top = 5 * (i / 30 | 0) + 'px';
await new Promise(resolve => { setTimeout(resolve, Math.random() * 500); });
el.style.background = 'black';
return 2 * i;
}).then(results => {
console.log(results.length, results.every((x, i) => x === 2 * i));
});
i {
background: grey;
transition: background 0.3s ease-out;
position: absolute;
width: 5px;
height: 5px;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)