Skip to content
uupaa edited this page Apr 26, 2016 · 26 revisions

Thread.js は JavaScript の WebWorkers の機能をラップし、より使いやすい形で提供するラッパーライブラリです。

  • メインスレッド(MainThread)と、メインスレッドから生成したワーカースレッド(WorkerThread)との間でメッセージのやり取りができます

  • ワーカースレッド の生成は、new Thread(...) で行います

  • メインスレッド から ワーカースレッド へのメッセージの送信は、Thread#post(...) で行います

    +--------+                              |                       +-------------+
    | Thread |                              |                       | ThreadProxy |
    +---+----+                              |                       +------+------+
        |                                   |                              |
        |   Thread#post()                   |                              |
       [A]--------------------------------------------------------------> [B]
        |                                   |                              |
        |                                   |           event.postback()   |
       [D] <--------------------------------------------------------------[C]
        |                                   |                              |
        |                                   |                              |
    
    
    
    <<MainPage>>                            |   <<Worker>>
    ========================================|=============================================
                                            |
    thread = new Thread("worker.js");       |   proxy = new ThreadProxy(function(args, event) {
    // [A]                                  |       // [B]
    thread.post(args, null, function(args) {|
        // [D]                              |       event.postback(); // [C]
    });                                     |   });
    
  • ワーカースレッド から メインスレッド へのメッセージの送信は、ThreadProxy#post(...) で行います

    • ワーカースレッドからメインスレッドを呼び出し、結果を受け取る(ポストバック)機能はありません
    +--------+                              |                       +-------------+
    | Thread |                              |                       | ThreadProxy |
    +---+----+                              |                       +------+------+
        |                                   |                              |
        |  Thread#post()                    |                              |
       [A]--------------------------------------------------------------> [B]
        |                                   |                              |
        |                                   |          ThreadProxy#post()  |
       [D] <--------------------------------------------------------------[C]
        |                                   |                              |
        |                                   |                              |
    
    
    <<MainPage>>                            |   <<Worker>>
    ========================================|=============================================
                                            |
    thread = new Thread("worker.js",        |   proxy = new ThreadProxy(function(args) {
                        function(args) {    |       // [B]
        // [D]                              |       proxy.post(); // [C]
    });                                     |   });
    thread.post(); // [A]                   |
    
  • ワーカースレッドのライフサイクル(生成/終了)をケアします

    • ワーカースレッドの強制終了や、終了理由(exitCode)を取得できます
    • ワーカースレッドに安全に終了する機会を与えます
      • ワーカースレッドは必要に応じて終了を引き伸ばしたり、拒否することも可能です
    +--------+              +-------------+  +-------------+  +-------------+  +-------------+
    | Thread |              | ThreadProxy |  | ThreadProxy |  | ThreadProxy |  | ThreadProxy |
    +---+----+              +------+------+  +------+------+  +------+------+  +------+------+
        |                          |                |                |                |
        |     ThreadProxy#close()  |                |                |                |
        | <------------------------+                |                |                |
        |                          x                |                |                |
        |     throw new Error()                     |                |                |
        | <-----------------------------------------+                |                |
        |                                           x                |                |
        |     unchaught exception                                    |                |
        |     (maybe script error)                                   |                |
        | <----------------------------------------------------------+                |
        |                                                            x                |
        |                               Thread#close()                                |
        +---------------------------------------------------------------------------> | closeRequestHandler
        |                                                                             +------+
        |                                                                             |      | yes() or no()
        |                               postMessage("YES") or postMessage("NO")       | <----+
        | <---------------------------------------------------------------------------+
        |                                                                             x
        |
    
  • スレッドプールをサポートします

    • スレッドプールにワーカースレッドを登録し、輪番でジョブを割り当てる事ができます
    +------------+              +--------+ +--------+
    | ThreadPool |              | Thread | | Thread |
    +-----+------+              +----+---+ +----+---+
          |                          |          |
          |                          |          |
          |  ThreadPool#add(Thread)  |          |
         [B] <----------------------[A]         |
          |                          |          |
          |  ThreadPool#add(Thread)  |          |
         [D] <---------------------------------[C]
          |                          |          |
          |                          |          |
          |                          |          |
          |    ThreadPool#post()     |          |
         [E]----------------------> [F]         |
          |                          |          |
          |    ThreadPool#post()     |          |
         [G]---------------------------------> [H]
          |                          |          |
          |    ThreadPool#post()     |          |
         [I]----------------------> [J]         |
          |                          |          |
          |                          |          |
    
    
    <<MainPage>>                            |   <<Worker>>                                          |   <<Worker>>
    ========================================|=======================================================|===========================================
                                            |                                                       |
    pool = new ThreadPool();                |                                                       |
    thread1 = new Thread("worker.js");//[A] |   proxy = new ThreadProxy(function(args, event) {     |
    pool.add(thread1); // [B]               |       // [F][J]                                       |
                                            |   });                                                 |
    thread2 = new Thread("worker.js");//[C] |                                                       |   proxy = new ThreadProxy(function(args, event) {
    pool.add(thread2); // [D]               |                                                       |       // [H]
                                            |                                                       |   });
    pool.post();  // [E]                    |                                                       |
    pool.post();  // [G]                    |                                                       |
    pool.post();  // [I]                    |                                                       |
    

WebWorkers を学ぶ

Thread.js を理解するために、 JavaScript におけるスレッドモデル(WebWorkers) について以下のポイントを抑えておくと良いでしょう。

  • まずは、HTML5 Rocks の記事 ウェブ ワーカーの基本 を読みましょう

  • Thread#post で送信するメッセージは Structured clone によって、自動的にコピーが作成されポストされます

  • 次々とメッセージを流し込む事ができます

    • 一つのワーカースレッドに対して次々とメッセージをpostできます
    • ワーカースレッドからメインスレッドに対しても、次々とメッセージをpostできます
    • メッセージはキューイングされ、一つの Worker Context に対して複数のプログラムカウンタが生成されている状態と考えると分かりやすいかもしれません
  • 同時に大量のワーカースレッドを生成するとブラウザがクラッシュします

Clone this wiki locally