52

問題

ブラウザーによって生成できる Web ワーカーの数に制限があることを発見しました。

メイン 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 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>

test.worker.js

self.onmessage = function(event) {
    var i = event.data; 

    self.postMessage(i);
};

これにより、Firefox (バージョン 14.0.1、Windows 7) を使用している場合、コンテナーに 20 行の出力しか生成されません。

質問

これを回避する方法はありますか?私が考えることができる唯一の2つのアイデアは次のとおりです。

1) Web Worker のデイジー チェーン接続、つまり、各 Web Worker が次の Web Worker を生成する

例:

<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>

2) Web ワーカーの数を有限数に制限し、その制限で動作するようにコードを変更します (つまり、有限数の Web ワーカー間で作業負荷を共有します) - 次のようなもの: http://www.smartjava.org /content/html5-easyly-parallelize-jobs-using-web-workers-and-threadpool

残念ながら、#1 は機能していないようです (ページの読み込み時に生成される Web ワーカーの数は限られています)。他に考慮すべき解決策はありますか?

4

4 に答える 4

14

私の経験では、あまりにも多くのワーカー (> 100) がパフォーマンスを低下させます。私の場合、FF が非常に遅くなり、Chrome がクラッシュすることさえありました。さまざまな量のワーカー (1、2、4、8、16、32) でバリアントを比較しました。ワーカーが文字列の暗号化を実行しました。ワーカーの最適な数は 8 であることが判明しましたが、ワーカーが解決しなければならない問題によって異なる場合があります。

ワーカーの数から抽象化するための小さなフレームワークを構築しました。ワーカーへの呼び出しはタスクとして作成されます。許容される最大数のワーカーがビジー状態の場合、新しいタスクがキューに入れられ、後で実行されます。

このようなアプローチで労働者をリサイクルすることが非常に重要であることが判明しました。アイドル状態のときはプールに保持する必要がありますが、頻繁に new Worker(...) を呼び出さないでください。worker.terminate() でワーカーを終了させて​​も、ワーカーの作成・終了とリサイクルでは性能に大きな差があるようです。

于 2013-07-14T21:11:09.250 に答える