2012-06-02 12 views
8

一部のエンジンが内部データ構造へのアクセスを同期しないため、DWScriptがスクリプト内のスレッドを使用できるかどうかを知りたいと思います。DWScriptはスレッドセーフですか?

+0

-1この質問は、ドキュメント、DWScriptプロジェクトウェブサイトのトップページ、ウェブ検索などを読むことによって簡単に答えられます。質問をする前に少し努力してください。 –

+1

答えが見つけやすいのであれば、それを何度もスキップしなければなりません。 – FHannes

+4

@david:誰もがrtfmだけであれば、スタックオーバーフローはありません:) –

答えて

4

アルノーは、キーポイントが得られた:

  • 各コンパイラのインスタンスは一度に一つのスレッドから呼び出すことができます。複数のコンパイラー・インスタンスを同時に複数のスレッドで呼び出すことができます。特定のコンパイラー・インスタンスは、複数のスレッドから使​​用できます。
  • 各コンパイルされたプログラムは複数の実行を持つことができ、各実行はそれぞれのスレッドで実行できます。また、特定の実行は、一度に1つのスレッドだけがそれを使用する場合、複数のスレッドによって使用することができます。
  • 各実行には変数のための独自の領域があり、独自のスタック、オブジェクトインスタンスはヒープ上にあり、技術的には実行間で共有することができますが、ロック機構はありません。
  • 公開されているクラスや関数を使用すると、スクリプトエンジンは同期やロックを実行しません(TdwsUnit、RTTIなど)。スレッド内のスクリプトの実行を実行している場合)、そう、あなただけのスレッドセーフなものを公開してください(RTL & VCLの多くは、スレッドセーフで開始するではないので、RTTIのためにそれについては特に注意してください)

スクリプトの複数の実行を実行するのはDelphiで複数のスレッドを持つのと似ていますが、新しい実行にはそれぞれ独自のスタック(Delphiスレッドなど)だけでなく、独自の変数空間もあります(Delphiでは、 var "どこでも)。また、DWScriptの実行は独自のスレッドにする必要はなく、スレッド間で移動したり、スレッド数を少なくしてポーリングしたり使用したりすることができます(唯一の制限は、上記の通り)。

スクリプト関数内でスレッド(および対応する実行)を生成する関数を公開することはできませんが、実行間の通信は共有変数を介さずに行われます(Delphiで誘惑されるように)あなた自身の公開関数(または外部変数)、戻り値(「評価」アプローチ、単体テスト参照)、「共有」オブジェクトインスタンス、または「グローバル変数」を使用しなければなりません。

"グローバル変数"とは、実行間のデータ交換に使用できるdwsGlobalVarsFunctions.pasで定義されている関数を意味します。それらをアクティブにするには、あなたのプロジェクトのどこかに "uses dwsGlobalVarsFunctions"を置いてください。

これらは、同じDelphiプロセス内で実行されているすべてのスクリプト実行で名前付きバリアントを格納および取得することができるRead/WriteGlobalVar関数のセットを公開し、読み込みは&の書き込みはスレッディングの観点から「不可分」です。

+1

これで、DWS「神父」(または新しいパパ)を持つニース! :) –

+0

TdwsProgramExecutionオブジェクトがスレッドで実行されているとき、別のスレッドがTdwsProgramExecution.EndProgramを安全に呼び出すことはできますか? – FHannes

+0

いいえ、しかし、Stop(これはBeginProgram/RunProgramで手動ではなくExecute()で実行した場合にも機能します)を呼び出すことができます。それは、スクリプトがその制御下でできるだけ早い時期に打ち切られるようにします。スクリプトでDelphi関数が実行されている場合、その関数から戻った後でのみ停止します。 EndProgramはクリーンアップを実行し、実行スレッドから呼び出されることを意味します。 –

3

DWSのドキュメントを開く必要はありませんでした。古いコードベースが制限を中心に構築されている間、例えば

は、[DWS]が1つのコンパイル済みスクリプトの複数のスレッドセーフな実行が可能である::)

ちょうど見at this StackOverflow answer by Ericを取りますコンパイルされたスクリプトは、一度に1つのスレッドだけが実行できるということです。要するに

DWSコンパイラはスレッドセーフではありません
  • :あなたは、コンパイラのインスタンスを共有することはできません(1つのスレッド内で実行スタックを作成する必要があり、あなたは一つのスレッドを必要としますコンパイラインスタンスごとに)。
  • スレッドごとに1つの実行インスタンスを使用する場合、DWS実行はスレッドセーフです。複数のスレッドで同じコンパイル済みスクリプトを実行できます。
  • スレッド間の通信はAFAIKでは使用できませんが、同期が必要な場合はDelphiコードを使用することができます。

もちろん、ここにはthe official documentation page about thread safety in DWSです。

あなたが望むようになりました各実行だけでそのヒープ&スタックのためのメモリを使用しますが、与えられたIdwsProgram用など、多くのプログラムの実行を持つことができ、コンパイル済みの式ツリーが共有されています。両方の新しいインターフェイスは、リファレンスカウントのメモリ管理を使用します。

+1

これを読んで、私はすでにこれを知っていることに気がつきましたが、間違っていなければ、それは私の質問にはあまり答えません...私は複数のスレッドで同じスクリプトを実行したくないので、 1つのスクリプトの中で複数のスレッドを実行しています... – FHannes

+1

AFAIKこれまでのところ、実行クラスの実装を理解していますが、設計上不可能です。 TThreadなどはありません。唯一の可能性は、それぞれのスレッド内でいくつかのスクリプトを実行することです(これはもちろん可能です).3番目のポイントに書いたのと同じように、スクリプト間でIPCまたはミューテックスを試してみてください:スレッド通信最初から入手できます。私はむしろ、Delphiクラス(例えばDWTIにRTTIを使用して公開されている)によって利用可能ないくつかの共有データ構造を持つステートレスアーキテクチャを推奨したいと思います。 –

関連する問題