V8の使用、パート3

V8の使用、パート3



パート3.マルチスレッド、拡張機能、およびコード設計



パート2はこちら: habrahabr.ru/blogs/development/72592



パート1はこちら: habrahabr.ru/blogs/development/72474







- マルチスレッド



マルチスレッドはV8に単純に実装されています。そうではありません。 一般的に。 ある時点でV8を使用できるスレッドは1つだけであり、「使用」とは必ずしもJavaScriptのコンパイルまたは実行を意味するものではなく、テンプレートの作成、V8スタックへのオブジェクトの配置などを意味します。



このスプーン1杯の蜂蜜でタールの樽を甘くしてみましょう。



もちろん、このアーキテクチャ上のソリューションは、Googleプログラマーの未開発の結果ではありません。 V8の主な目的は、Chromeブラウザーであるクライアントアプリケーションです。Chromeブラウザーは、個別のタブごとに個別のプロセスを起動します。 サーバーアプリケーションも同じスキームに従う必要があります。 私たちのサーバー製品は、いわゆる 「作業」プロセス。名前付きパイプはメインプロセスに結合され、処理のためのメッセージを受け取ります。 これにより、マルチコアシステムを完全にロードし、Windows OS自体のプロセスマネージャーを使用してタスクを切り替えることができます。



V8ディスカッショングループには、「真の」マルチスレッドが必要な人が時々登場します。 さらに、彼らはグーグルのソースコードを長くて難しい編集する準備ができています。 通常、これらの議論の結果は次のような結論になります。現在のV8コードをマルチスレッドコードに変換することは非常に難しく、Google開発者自身によってのみ行われます。 詳細については、たとえばこちら(英語で、Googleグループv8-usersのメンバーである必要があります): groups.google.ru/group/v8-users/browse_thread/thread/44621a6efef0104f



ただし、V8は1つのスレッドでもよりスマートに管理できます。 V8の唯一の「キャプチャ」には、Windowsの通常のクリティカルセクションを使用できますが、V8自体のツールであるLockerクラスを使用することをお勧めします。 このクラスのコンストラクターはV8を「キャプチャー」しようとして(リリースされるのを待っています)、デストラクタはV8を「解放」しています。 したがって、V8を使用してマルチスレッドアプリケーションで安全に動作するコードは次のようになります。



{

v8::Locker locker;

// V8

// ...

}

// V8 ""



* This source code was highlighted with Source Code Highlighter .








問題は、JavaScriptコードから頻繁にC ++コードを呼び出すことです。 たとえば、この記事のパート2のdbliteクラスはデータベースで機能します。 明らかに、その動作中、V8は何もしないでアイドル状態です。実際、C ++コードはほとんどの場合V8と対話せず、入力/出力を処理します。



そのため、V8にはUnlockerクラスが用意されており、しばらくするとV8を「リリース」できます。 コンストラクターのUnlockerクラスはV8を「リリース」し、デストラクタでは(Lockerクラスとは対照的に)再び「キャプチャ」します。 美しさは、ロッカーを互いに入れ子にすることができ、Unlockerがこれを認識して正しく動作することです。つまり、ロッカーの深さに関係なくV8をリリースします。



これは、dbliteクラスを使用した記事のパート2からの例を修正することで説明できます。 Open関数を新しい知識で書き直します。



Handle<Value> Open( const Arguments& args)

{

if (args.Length() < 1) return Undefined(); // ? !

dblite* db = unwrap_dblite(args.This()); // dblite

string sql = to_string(args[0]); // C++, to_string

bool r;

{

Unlocker unlocker; // V8

r = db->open(sql.data()); // C++

} // unlocker " " V8

return Boolean::New(r);

}



* This source code was highlighted with Source Code Highlighter .








Open()はV8との対話の期間のみV8を「取得」し、すべての入出力は別のスレッドで実行できます。



少し叙情的な余談。 Unlockerの機能を調査しているときに、バグに遭遇しました。その結果、V8を使用する単純なプログラムは1秒あたり100 MBを失いました。 ググロフツェフの功績として、私はこの問題が非常に迅速に解決されたと言わなければなりません。 現在、このバグはすでにtrunkブランチで修正されており、問題は解決されています。 詳細はこちらをご覧ください: code.google.com/p/v8/issues/detail?id=444



V8は、Lockerを介してV8への唯一のアクセスをキャプチャしようとするスレッドを基本的に切り替えることができます。 Locker :: StartPreemption()への呼び出しがあります。 おそらく、このソリューションはある時点で他のソリューションよりも便利になるでしょう。



- 拡張機能とコード設計



V8の批評家は(odnredredstvaであることに加えて)彼を非難し、あまりにも「ゆるい」コードストラップで。 実際、構造は少し面倒で、Googleはこの問題をプログラマー自身に任せています。 さらに悪いことに、多数の同じタイプのコールバック関数を宣言する必要があります。それらをグローバルスコープで通常の関数にすると、ハッシュも提供されます。



C ++クラスをラップするV8クラスの最も単純なソリューションは、次のようになります。特別なC ++クラス-ラッパーを宣言します。 コールバック関数により、静的メソッドになります。 オブジェクトのテンプレートは単一のコピーに保存する必要があるため、静的にすることもできます。 V8との類推により、New関数を開始します。 次のようになります。



class ScriptDatabase

{



// JavaScript dblite



//

static Handle<Value> Open( const Arguments& args);

static Handle<Value> Execute( const Arguments& args);

static Handle<Value> Select( const Arguments& args);

...



//

static Handle<Value> ErrorCode(Local< String > name, const AccessorInfo& info);

...



// js- obj C++ ScriptDatabase

static dblite* Unwrap(Handle<Object> obj);



//

static Persistent<Object> New( const char * db_name = 0);



// ,

static Handle<Value> Create( const Arguments& args);



};



* This source code was highlighted with Source Code Highlighter .








テンプレートに関しては、もちろん、創造性の大きな範囲があります。 そしてもちろん、すでにいくつかの解決策があります。 たとえば、cproxyv8プロジェクトを見ることができます: code.google.com/p/cproxyv8

これは、コードがcproxyv8を使用して判明する方法です: code.google.com/p/cproxyv8/wiki/Usage



V8の使用を簡素化するプロジェクトは他にもあります。 たとえば、v8-juice: code.google.com/p/v8-juice

v8-juiceは、任意のDLL機能をjavascript(http://code.google.com/p/v8-juice/wiki/Plugins)にロードするためのAPIと、V8タイプをC ++タイプに変換する便利な方法(http://コード.google.com / p / v8-juice / wiki / ConvertingTypes)。 そして何か他のもの。



これらはサードパーティのプロジェクトであり、ご自身の責任で使用してください。 私が決断したとき、私はGoogleコードのみを管理していました。最初はこれらの拡張機能に出くわしていなかったからです。 おそらく今私は何かを使うだろう...






All Articles