2013-06-08 15 views
27

にマルチスレッド私は、IronPythonの中に「スクリプトクラス」を持っている、と私のアプリ内のスクリプトは、そのインスタンスのメソッドを呼び出すことで動作します。私は、複数のスレッドからスクリプトを呼び出すことを実装する必要があります。それを行う正しい方法は何ですか?は、IronPythonの

私は複数の問題があります。

  1. ScriptScopeスレッドセーフですか?情報は矛盾している。 ScriptScope's documentation says「ScriptScopeはスレッドセーフではありませんホストはロックのいずれか複数のスレッドが同じモジュールにアクセスすることができなければならないとき、またはスレッドごとにコピーを作成する必要があります。」 ScriptScopeスレッド間で共有できるようにしかし、IronRubyのは、同じDLR及びが「ScriptRuntime、たScriptEngine、及びScriptScopeスレッド間で使用されるように設計安全なすべてのスレッドである。具体的には、ScriptScopeは、スレッドセーフなデータストアを使用すること@JimmySchementi saysを使用します"

  2. 複数のScriptScopeを作成すると、同じ初期化スクリプトを複数回実行することになります。 、のは、私が10個のPythonスクリプト・ファイルを実行することを想定してみましょう5つのアセンブリをインポートし、全体的に「スクリプトオブジェクト」準備をするコードのかなりを実行します。それぞれのスレッドごとに同じコードをたくさん実行する時間とメモリのコストを避ける方法はありますか?

  3. ThreadStaticAttributeを適用し、それがある)ScriptScope変数スレッド静的作って行くためにTask.Run方法によって利用されるすべてのスレッドの初期化を実行していますか?複数のスコープのコストが高いためか、私には、同時実行の制限とTaskSchedulerを使うべきなのでしょうか?全体的に

:正しく複数のスレッドで異なる引数で同じスクリプトを実行している実装する方法スクリプトは同時に実行する必要があり、競合状態によってクラッシュしてはなりません。

+3

私はあなたのために感じます。私は、Microsoftが正式にそれをサポートしなくなって以来、あらゆる側面で欠けているironpythonとironrubyの両方のドキュメントを発見しました。 –

答えて

-1

以来、私は一般的なものを持っているあなたは、具体的な答えを得ているように、それは見ていません。

私の以前の仕事でIronPhythonを使用していて、マルチスレッドを処理するのは不可欠なので、IronPythonを実動システム上のマルチスレッド環境で実行することは可能です。

IronPython内でロックを使用しているのか、IronPython内部のロックに依存しているのか分かりません。

私は次のように提案します:

a)自分でテストを実行してください。安全かどうかを証明する簡単なテストを書くことができます。

[Test] 
    public void TwoThreadsWithTheirOwnContexts() { 
     //Create two threads 
     var tasks = new Task[2]; 
     tasks[0] = Task.Factory.StartNew(PrintSomethingInIronPython1); 
     tasks[1] = Task.Factory.StartNew(PrintSomethingInIronPython2); 
     Task.WaitAll(tasks); 
    } 

b)はとにかくロックを追加します。次のコードのように、粗として何かが良いスタートである可能性があります。あなたのコードでロックを解除するのは大きな問題ではないかもしれませんし、不確実性を取り除くこともできます。

最終的に、スレッドセーフではないことが判明した場合は、それが(テスト)であることを証明するか、安全にプレーする(独自のロック)必要があります。何にかかわらず、マルチスレッドテストを行うことは、とにかくプロダクションに入る前に行う必要があります。私はあなたが最初にそれらを行うことによっていつでも本当に緩んだとは思わない。

Re 2: もう一度お勧めします。一度初期化を行い、その後これらのスレッドを再利用するプールスレッドを作成します。

+2

私はスレッドの安全性が単体テストで確認できるとは思わない。 –

+0

@JeffreyZhao同意 - スレッドセーフは、ユニットテストケースではなく、何かの本質的な品質です。 – data

2

1.

ScriptScopeのドキュメントは、それはスレッドセーフではないと言う場合は、それを信じるか、あなたはそれを信じているように、少なくとも行動します。 @JimmySchementiは現在の実装を見て、現在スレッドセーフであると考えているかもしれませんが、次のメジャーリリースはもちろんのこと、クラスの次のパッチでどのように動作するかは保証されません。

はい、ScriptScopesをそれぞれ初期化する必要があります。私はあなたが必要とするScriptScopesの数を最小限にしようとします。これを行う方法はあなたの設定に依存します。関係するスレッドの主な目的がScriptScopeをホストすることである場合は、ThreadLocalが1つの各スレッドにThreadPoolを使用する必要があります(< ScriptScope)。これらのスレッドがスクリプトを実行するだけでなく他の処理を行っている場合、ScriptScopesを格納するオブジェクトプールが必要で、各スレッドはScriptScopesをチェックアウトし、作業を行い、ScriptScopeを解放できます。あなたはこの道を行けば

3.

はThreadStatic上ThreadLocalを好みます。

0

これはあなたが正しくあなたを理解した場合、スクリプトでこれを行う方法です。

https://github.com/dretax/Python-Plugins/blob/master/PlutonPlugins/PluIRC/PluIRC.py#L154

は、それは完全に別の引数で、同じことの新しいスレッドを起動し、そのスクリプトが何をするかを参照してください。

完全にスレッド化され、IronPythonを使用している場合に表示されるpyファイルです。 これはスレッドを正しく行う方法であり、他の方法ではありません。