HTML5 「Web Workers」でマルチスレッドプログラミング

以前の記事「JavaScriptのマルチスレッド(?)はマルチコアの恩恵を受けるのか?」で現在主流のブラウザ(HTML4)のJavaScriptでは、マルチスレッドプログラミングを行うことができないという結論に至りました。

ただし、現在主流のブラウザではマルチスレッドプログラミングが行えないだけであって、次のバージョンであるHTML5からは、ちゃんとマルチスレッドプログラミングを行うことができます。

それは、HTML5で追加される「Web Workers」という機能を使用することで実現できます。

今回は、本日(6月9日)に正式リリースされたばかりの、HTML5をサポートする「Safari 4」を使用して、Web Workersを使用したマルチスレッドプログラミングを行って、マルチコアによるパフォーマンス向上の恩恵を受けるかどうか、実験で確かめてみようと思います。

さっそくサンプルコード

百聞は一見にしかずです。

Sample.html

<html>
  <head>
    <title>HTML5「Web Workers」先取り</title>
  </head>
  <body>
    <p>素因数分解{from:100001, to:150000}の処理時間: <span id="result1"></span></p>
    <p>素因数分解{from:150001, to:200000}の処理時間: <span id="result2"></span></p>

    <script>
      var start = new Date();
      var worker1 = new Worker('job1.js');
      var worker2 = new Worker('job2.js');
      worker1.onmessage = function (event) {
        document.getElementById('result1').textContent = (new Date() - start) + "ms";
      };
      worker2.onmessage = function (event) {
        document.getElementById('result2').textContent = (new Date() - start) + "ms";
      };
    </script>

  </body>
</html>

job1.js

function factorization(number){
    var n = 2;
    var answer = new Array();

    while (number > 1) {
        if (number % n == 0) {
            answer.push(n);
            number /= n;
        }
        else
            n++;
    }
    return answer;
}

var job = {from:100001, to:150000};
for (var i = job.from; i <= job.to; i++)
    factorization(i);  

postMessage(null);

job2.js

function factorization(number){
    var n = 2;
    var answer = new Array();

    while (number > 1) {
        if (number % n == 0) {
            answer.push(n);
            number /= n;
        }
        else
            n++;
    }
    return answer;
}

var job = {from:150001, to:200000};
for (var i = job.from; i <= job.to; i++)
    factorization(i);  

postMessage(null);

解説

まだ、勉強したてで知り尽くしていませんが解説します。

var worker1 = new Worker('job1.js');
var worker2 = new Worker('job2.js');

上記のコードでスレッドを2つ作成しています。
実際にスレッドに処理させる内容は外部JSファイルに記述します。

worker1.onmessage = function (event) {
    document.getElementById('result1').textContent = (new Date() - start) + "ms";
};
worker2.onmessage = function (event) {
    document.getElementById('result2').textContent = (new Date() - start) + "ms";
};

上記のコードは外部JSファイルにてpostMessageメソッドが呼び出された時の受け口となるイベントを登録します。postMessageメソッドの引数を指定すると、onmessageイベントの引数であるevent.dataプロパティに格納されて親に渡すことができます。

このonmessageイベントが唯一のデータの受け口です。「Wokerスレッド→親」という向きしかありません。親からWokerスレッドへデータを渡すことはどうやらできないようです。

色々試してみたのですが、呼び出し元で宣言した変数を、外部JSファイル内で参照することはできませんでした。恐らくこれはスレッドセーフではないオブジェクトにアクセスすることを防ぎ、マルチスレッドによる不具合を起こさせない為の仕様だと思われます。

マルチコアの恩恵を受けるかどうか

実行してCPUのグラフを観察しました。

実物はこちら
※Web Workersに対応しているブラウザじゃないと動きません。現時点で標準対応しているのはSafari 4だけです。

実行結果(Safari 4)

最終的に約13秒で結果が返ってきました。

データ量の割合的に、ちゃんと並列処理されているようです。

ちなみに、シングルスレッドバージョンだと約25秒で結果が返ってきます。

CPUモニターはどうでしょうか。

実行結果 (CPUモニタ)

お、ちゃんと二つのCPUを使っているようです!

まとめ

  • 次世代WebであるHTML5からマルチスレッドプログラミングが可能
  • また、マルチコアCPUによるパフォーマンス向上の恩恵を受ける
  • スレッドセーフを保つため、自由度は高くない
日付: 2009/06/09

One Response to “HTML5 「Web Workers」でマルチスレッドプログラミング”

  1. JavaScriptのマルチスレッド(?)はマルチコアの恩恵を受けるのか? Says:

    [...] 続編「HTML5 「Web Workers」でマルチスレッドプログラミング」を読む ブログランキング参加中! 参考になりましたら、クリックをお願いします。 にほんブログ村 / 人気ブログ [...]

コメントを残す

You must be logged in to post a comment.

Copyright ©ko-ketsu All Rights Reserved
  • 人気の投稿

  • 最近の投稿

  • 最近のコメント

  • 固定ページ

  • カテゴリー

  • メタ情報