項目 | WebWorkers有無で共通化する仕様 |
---|---|
worker
宣言のURL |
main script内で宣言する外部script(for_url.js)のURLは
index.htmlからの相対pathで記述する
なお、main内の関数をcreateObjectURLで指定する方法は 次に示すimportScriptsを使用しないcaseに限られる |
worker
外部script |
共通化する処理jobを別のscript(for_importScripts.js)に定義してimportする
importするscriptのpathは外部script(for_url.js)からの相対pathで記述する importするscriptが複数ある場合、comma区切りで読み込み順に並べる(配列渡し不可) これより外部scriptは最も単純に次のように記述される
e.dataがmainから受け取るcopy-data(参照を持たないJSON形式) なお、外部scriptに変更を加えた場合、 "cacheの消去とhard再読込み"をしないと反映されないcaseがあるので留意する |
worker
同時並列化 |
threadを同時並列化する場合、同時並列数self.n_threadのWorkerを宣言する
なお、overheadとthroughputのtrade-offに応じて最適なn_threadを選択する 通常、memory sizeが問題にならない場合、最適なn_thread=CPU-core数*(1~2) |
main/worker
共通化するjob定義 |
mainとworkerそれぞれでimportする共通のscriptにjobを定義する
mainから受け取ったdataを処理した後、同様のdataを返却する いずれかのerror発生場所を特定するためにwindow objectの存在可否を判定する なお、workerからはmainのwindowやdocumentにaccessできないことに留意する そのため、ここで定義するjobは並列化向きのmedia処理や数値計算が一般的と考えられる |
main
依頼処理 |
mainからworkerにまとめてarr_dataを渡すhandler_workerを用意し、排他処理を実施する
最も上流の実行命令直後とhandler_worker.runを呼ぶ関数の最初にlock判定を加える
追加依頼を受けないlock状態にすることで最大thread数に制限を設ける さらに、threadの終了処理を確実に実施してからlock状態を解除する なお、後述する再初期化処理init_workerをhandler_worker.runの直前に実施する 他方、WebWorkers非対応の環境ではSingle-threadで実行する 共通化したjob_importedであるself.job_workerをforEachで順番に実行し、 後述する受取り処理self.callbacks_worker.onmessageに返却dataを渡す 同様にerrorをcatchして後述するerror処理self.callbacks_worker.onerrorに渡す |
handler_worker
実行処理 |
上記のhandler_worker.runの関数を以下に示す
WebWorkers非対応||lock状態の場合、即座にfalseを返却する それ以外の場合、lock後、同時並列化したworkerの中断terminateを判定をしながら postMessageで外部scriptに繰り返しdataを送信する なお、繰り返しnew Workerを宣言する必要はないことに留意する また、postMessage後のerror処理の伝播はworkerをterminateしても中断できないため、 構文error等は事前に弾いてrunを実行しない方が望ましい |
main
受取り処理 error処理 |
workerに登録する受取り処理とerror処理のcallbackをmain内に定義する
workerからはmain依頼順とは順不同にdataが返却されるため、 依頼順data.iに結果が並ぶように配列に代入してarr_data_out[data.i] = data Object.keys(self.arr_data_out).lengthが 依頼したdataの長さself.arr_data_in.lengthに一致すれば終了判定する また、終了処理を実施する error発生時や中断時、body.onbeforeunload時も同様の終了処理を実施する error発生時、上記の配列を初期化するself.stop_worker(true) なお、callbackは別のscopeから呼ばれるため、thisをinstance selfでbindする 元のcallbackを不変の前提で直接bindする場合、再代入が必要であることに留意する callback = callback.bind(self); |
handler_worker
中断・終了処理 |
handler_workerの中断・終了処理の関数を以下に示す
worker.terminateをcallして全threadを強制終了する また、memoryを解放するself.workers = [] さらに、lock状態を解除する なお、workerをteminateした時点で再利用不可のため、 再利用する場合、必要になった時点でself.workersを再宣言する |
main
中断・終了処理 |
上記のhandler_worker.terminateをcallするmainの中断・終了処理を以下に示す
なお、terminate直前にlock判定して中断log表示等を1回のみ実施する |
main
再初期化処理 |
mainの再初期化処理を以下に示す
self.workersを再宣言するhandler_worker.re_init直前に再度terminateを実施する なお、new Workerが重複宣言されないように留意する |
try~catch処理
Ver.1.82.15追加 |
擬似codeを以下に示す
main処理の上流でcatchしてerror処理をswitchする(原則、多用しない) 非同期処理の場合、callbackの中に記述する なお、lock処理も同様に完結させる(別の処理からflagを操作しない) |