2014年6月29日日曜日

Web Worker をメインスレッドの実行時に動的に生成してeval的な使い勝手で扱う方法

var b = new Blob( [ 'console.log( "It is blob!" )' ], { type: 'text/javascript' } )
var u = URL.createObjectURL( b )
var w = new Worker( u )

いますぐF12(SafariやOperaではキーバインドが異なるけど、つまり「開発者ツール」のショートカットキー)を押して、コンソールに上記の3行を叩き込んでみましょう(╹◡╹)

動作したでしょうか? "It is blob!" と表示されているという事は、どうやらこの方法はうまく行くようです(╹◡╹)

Blob ctor (旧: BlobBuilder [deprecated] から統合)で任意のWebでクライアントが扱うファイル相当のオブジェクトを生成し、URL.createObjectURLで生成したBlobオブジェクトからURLオブジェクトを生成し、Worker cotr の引数(URL)に渡すと、どうやらうまくWeb WorkerによるWeb曰くの別スレッド(実際にはほぼ別プロセス+プロセス間通信と思った方が良さそう、いまのところはね)が起動して、スクリプト内容が実行され、 console.log により出力が得られました。

この方法だと、別途スクリプトファイルを用意しなくても良いのが楽とかそんな事よりも、つまり Web のメインスレッドから動的にスクリプトを記述してそれをWorkerにタスクとして投げられる、いわば eval 的な使い勝手で Web Worker を使えるという事です。

それがどう嬉しいかというと、一般にC++コードでラムダ式でタスクを生成してstd::threadに放り投げるような場合のキャプチャーの感覚で、 Emscripten ビルドでもこの方法で実装してオブジェクトをJSONにシリアライズして Worker に渡すスクリプトに埋め込める。 std::future 風に get する事も Worker に渡すスクリプトの最後にメインスレッドへのメッセージングを入れておけば、まがいものくらいには対応できる。

WebがWorkerに共有メモリーを実装し、Emscriptenがpthreadに対応する日もそう遠くはないらしいけど、さしあたってはこういう事ができるのなら、まあまあ、それなりに、対応はできるかな。


参考

0 件のコメント:

コメントを投稿