Javascript 网络工作者数量限制
问题 我发现浏览器可以产生的网络工作者的数量是有限制的 示例 主HTML/JavaScriptJavascript 网络工作者数量限制,javascript,Javascript,问题 我发现浏览器可以产生的网络工作者的数量是有限制的 示例 主HTML/JavaScript <script type="text/javascript"> $(document).ready(function(){ var workers = new Array(); var worker_index = 0; for (var i=0; i < 25; i++) { workers[worker_index] = new Worke
<script type="text/javascript">
$(document).ready(function(){
var workers = new Array();
var worker_index = 0;
for (var i=0; i < 25; i++) {
workers[worker_index] = new Worker('test.worker.js');
workers[worker_index].onmessage = function(event) {
$("#debug").append('worker.onmessage i = ' + event.data + "<br>");
};
workers[worker_index].postMessage(i); // start the worker.
worker_index++;
}
});
</head>
<body>
<div id="debug">
</div>
使用Firefox(版本14.0.1,Windows 7)时,容器中只会生成20行输出
问题
有办法解决这个问题吗?我能想到的只有两个想法:
1) 以菊花链方式链接web工作人员,即使每个web工作人员生成下一个web工作人员
例如:
<script type="text/javascript">
$(document).ready(function(){
createWorker(0);
});
function createWorker(i) {
var worker = new Worker('test.worker.js');
worker.onmessage = function(event) {
var index = event.data;
$("#debug").append('worker.onmessage i = ' + index + "<br>");
if ( index < 25) {
index++;
createWorker(index);
}
};
worker.postMessage(i); // start the worker.
}
</script>
</head>
<body>
<div id="debug"></div>
$(文档).ready(函数(){
createWorker(0);
});
函数createWorker(i){
var-worker=new-worker('test.worker.js');
worker.onmessage=函数(事件){
var指数=事件数据;
$(“#调试”).append('worker.onmessage i='+index+“
”);
如果(指数<25){
索引++;
createWorker(索引);
}
};
worker.postMessage(i);//启动worker。
}
2) 将web工作人员的数量限制为有限数量,并修改我的代码以使用该限制(即,在有限数量的web工作人员之间共享工作负载)-类似如下:
不幸的是#1似乎不起作用(一次页面加载只会产生有限数量的web工作人员)。还有其他解决方案吗? < P>你在解决方案中链接你的工作人员的方法1弹劾垃圾收集器终止工作实例,因为在OnMead回调函数的范围内仍然有对它们的引用。 请尝试使用以下代码:
<script type="text/javascript">
var worker;
$(document).ready(function(){
createWorker(0);
});
function createWorker(i) {
worker = new Worker('test.worker.js');
worker.onmessage = handleMessage;
worker.postMessage(i); // start the worker.
}
function handleMessage(event) {
var index = event.data;
$("#debug").append('worker.onmessage i = ' + index + "<br>");
if ( index < 25) {
index++;
createWorker(index);
}
};
</script>
</head>
<body>
<div id="debug"></div>
var工人;
$(文档).ready(函数(){
createWorker(0);
});
函数createWorker(i){
worker=newworker('test.worker.js');
worker.onmessage=handleMessage;
worker.postMessage(i);//启动worker。
}
函数handleMessage(事件){
var指数=事件数据;
$(“#调试”).append('worker.onmessage i='+index+“
”);
如果(指数<25){
索引++;
createWorker(索引);
}
};
根据我的经验,太多工人(>100人)会降低绩效。在我的例子中,FF变得非常慢,Chrome甚至崩溃。我比较了不同数量工人的变异(1,2,4,8,16,32)。工作人员对字符串进行了加密。结果表明,8人是最佳的工人数量,但这可能有所不同,取决于工人必须解决的问题
我建立了一个小框架,从工人的数量中抽象出来。对工人的调用被创建为任务。如果允许的最大工作人数为忙碌,则新任务将排队并在稍后执行
事实证明,用这种方法回收工人是非常重要的。当他们空闲时,您应该将他们放在池中,但不要太频繁地呼叫新员工(…)。即使worker.terminate()终止了worker,创建/终止worker与回收worker之间的性能似乎也有很大差异。老问题,让我们重提它吧!准备肾上腺素 我一直在研究使用Web Workers隔离第三方插件,因为Web Workers无法访问主机页。我会帮助你解决你的方法,我相信你现在已经解决了,但这是为互联网。然后,我将从我的研究中提供一些相关信息 免责声明:在我使用您的代码的示例中,我修改并清理了代码,以提供不带jQuery的完整源代码,以便您和其他人可以轻松地运行它。我还添加了一个计时器,它以毫秒为单位提醒执行代码的时间 在所有示例中,我们都引用以下
genericWorker.js
文件
genericWorker.js
方法1(线性执行)
你的第一种方法几乎奏效了。它仍然失败的原因是,在完成工作之后,您没有删除任何工作人员。这意味着同样的结果(崩溃)将发生,只是速度较慢。您只需添加worker.terminate()代码>创建新辅助进程之前,从内存中删除旧辅助进程。请注意,这将导致应用程序的运行速度大大降低,因为必须创建、运行和销毁每个辅助进程,然后才能运行下一个辅助进程
Linear.html
它根据接收到的消息执行一些操作,并在内部保存数据。这太棒了。它允许mah插件开发者完全控制他们的插件。主应用程序实例化他们的插件一次,然后将发送消息给他们做一些动作
当我们想同时加载几个插件时,问题就出现了。我们不能那样做,那我们能做什么呢
让我们考虑一些解决方案
解决方案1(无状态)
让我们把这些插件变成无状态的。本质上,每当我们想让插件做一些事情时,我们的应用程序都应该实例化插件,然后根据它的旧状态向它发送数据
发送的数据
无状态工人.js
这可能行得通,但如果我们处理大量数据,这将开始看起来不是一个完美的解决方案。另一个类似的解决方案可能是每个插件都有几个较小的工作人员,并且每个插件之间只发送少量数据,但我对此也感到不安
解决方案2(状态恢复)
如果我们试图尽可能长时间地将工作进程保留在内存中,但如果我们确实丢失了它,我们可以恢复它的状态,该怎么办?我们可以使用某种调度器来查看用户一直在使用哪些插件(也许还有一些奇特的算法来猜测用户将来将使用什么),并将这些插件保存在内存中
关于这一点,最酷的部分是我们不再关注每个核心一个工人。由于工作进程处于活动状态的大部分时间都是空闲的,因此我们只需要担心它占用的内存。对于相当数量的工人(10到20人左右),这一数字根本不会很大。我们可以让主插件保持加载状态,而不经常使用的插件则可以根据需要进行切换。所有的插件都是w
<script type="text/javascript">
var worker;
$(document).ready(function(){
createWorker(0);
});
function createWorker(i) {
worker = new Worker('test.worker.js');
worker.onmessage = handleMessage;
worker.postMessage(i); // start the worker.
}
function handleMessage(event) {
var index = event.data;
$("#debug").append('worker.onmessage i = ' + index + "<br>");
if ( index < 25) {
index++;
createWorker(index);
}
};
</script>
</head>
<body>
<div id="debug"></div>
self.onmessage = function(event) {
self.postMessage(event.data);
};
<!DOCTYPE html>
<html>
<head>
<title>Linear</title>
</head>
<body>
<pre id="debug"></pre>
<script type="text/javascript">
var debug = document.getElementById('debug');
var totalWorkers = 250;
var index = 0;
var start = (new Date).getTime();
function createWorker() {
var worker = new Worker('genericWorker.js');
worker.onmessage = function(event) {
debug.appendChild(document.createTextNode('worker.onmessage i = ' + event.data + '\n'));
worker.terminate();
if (index < totalWorkers) createWorker(index);
else alert((new Date).getTime() - start);
};
worker.postMessage(index++); // start the worker.
}
createWorker();
</script>
</body>
<html>
<!DOCTYPE html>
<html>
<head>
<title>Thread Pool</title>
</head>
<body>
<pre id="debug"></pre>
<script type="text/javascript">
var debug = document.getElementById('debug');
var maxWorkers = navigator.hardwareConcurrency || 4;
var totalWorkers = 250;
var index = 0;
var start = (new Date).getTime();
function createWorker() {
var worker = new Worker('genericWorker.js');
worker.onmessage = function(event) {
debug.appendChild(document.createTextNode('worker.onmessage i = ' + event.data + '\n'));
worker.terminate();
if (index < totalWorkers) createWorker();
else if(--maxWorkers === 0) alert((new Date).getTime() - start);
};
worker.postMessage(index++); // start the worker.
}
for(var i = 0; i < maxWorkers; i++) createWorker();
</script>
</body>
<html>
<!DOCTYPE html>
<html>
<head>
<title>Repeated Worker</title>
</head>
<body>
<pre id="debug"></pre>
<script type="text/javascript">
var debug = document.getElementById('debug');
var totalWorkers = 250;
var index = 0;
var start = (new Date).getTime();
var worker = new Worker('genericWorker.js');
function runWorker() {
worker.onmessage = function(event) {
debug.appendChild(document.createTextNode('worker.onmessage i = ' + event.data + '\n'));
if (index < totalWorkers) runWorker();
else {
alert((new Date).getTime() - start);
worker.terminate();
}
};
worker.postMessage(index++); // start the worker.
}
runWorker();
</script>
</body>
<html>
<!DOCTYPE html>
<html>
<head>
<title>Repeated Thread Pool</title>
</head>
<body>
<pre id="debug"></pre>
<script type="text/javascript">
var debug = document.getElementById('debug');
var maxWorkers = navigator.hardwareConcurrency || 4;
var totalWorkers = 250;
var index = 0;
var start = (new Date).getTime();
function runWorker(worker) {
worker.onmessage = function(event) {
debug.appendChild(document.createTextNode('worker.onmessage i = ' + event.data + '\n'));
if (index < totalWorkers) runWorker(worker);
else {
if(--maxWorkers === 0) alert((new Date).getTime() - start);
worker.terminate();
}
};
worker.postMessage(index++); // start the worker.
}
for(var i = 0; i < maxWorkers; i++) runWorker(new Worker('genericWorker.js'));
</script>
</body>
<html>
var i = 0;
self.onmessage = function(e) {
switch(e.data) {
case 'increment':
self.postMessage(++i);
break;
case 'decrement':
self.postMessage(--i);
break;
}
};
{
action: 'increment',
value: 7
}
self.onmessage = function(e) {
switch(e.data.action) {
case 'increment':
e.data.value++;
break;
case 'decrement':
e.data.value--;
break;
}
self.postMessage({
value: e.data.value,
i: e.data.i
});
};
var i = 0;
self.onmessage = function(e) {
switch(e.data) {
case 'increment':
self.postMessage(++i);
break;
case 'decrement':
self.postMessage(--i);
break;
default:
i = e.data;
}
};
dom.workers.maxPerDomain