2013-06-08 29 views
27

Ich habe eine "Skript-Klasse" in IronPython und Scripting in meiner App funktioniert durch den Aufruf von Methoden auf seiner Instanz. Ich muss aufrufende Skripte von mehreren Threads implementieren. Was ist der richtige Weg?Multi-threading in IronPython

Ich habe mehrere Probleme auf:

  1. Ist ScriptScope Thread-sicher? Information ist widersprüchlich. ScriptScope's documentation says: "ScriptScope ist nicht threadsicher. Host sollte entweder sperren, wenn mehrere Threads auf dasselbe Modul zugreifen können, oder eine Kopie für jeden Thread erstellen." IronRuby verwendet jedoch dieselbe DLR und @JimmySchementi says, die "ScriptRuntime, ScriptEngine und ScriptScope sind alle threadsicher, für die Verwendung zwischen Threads entwickelt. Insbesondere verwendet ScriptScope einen Thread-sicheren Datenspeicher, so dass ScriptScope zwischen Threads geteilt werden kann . "

  2. Wenn ich mehrere ScriptScope s erstelle, würde das bedeuten, dasselbe Initialisierungsskript mehrmals auszuführen. Angenommen, ich führe zehn Python-Skriptdateien aus, importiere fünf Assemblies und führe insgesamt ziemlich viel Code aus, um das "Skriptobjekt" bereit zu machen. Gibt es eine Möglichkeit, die Zeit und die Speicherkosten zu vermeiden, indem Sie für jeden einzelnen Thread denselben Code ausführen?

  3. machen die variable ScriptScope gewinde statisch (das heißt, die Anwendung ThreadStaticAttribute) und Ausführen der Initialisierung für jeden Faden, der durch Task.Run den Weg zu gehen genutzt wird? Oder sollte ich eine TaskScheduler mit einer Grenze für Parallelität verwenden, weil die Kosten für mehrere Bereiche hoch ist?

Im Großen und Ganzen: , wie man richtig implementieren auf unterschiedliche Argumente in mehreren Threads das gleiche Skript ausgeführt wird? Skripte müssen gleichzeitig ausgeführt werden und dürfen aufgrund von Rennbedingungen nicht abstürzen.

+3

Ich fühle für dich. Ich fand die Dokumentation über Ironpython und Ironruby in jeder Hinsicht mangelhaft, da Microsoft aufhörte, sie offiziell zu unterstützen. –

Antwort

-1

Da es nicht so aussieht, als ob Sie eine konkrete Antwort bekommen, habe ich eine allgemeine Antwort.

Ein Kollege von mir verwendet IronPython in meinem vorherigen Job und Multithreading-Behandlung wäre wesentlich gewesen, so kann ich sagen, dass es möglich ist, IronPython in einer Multithread-Umgebung auf einem Produktionssystem zu laufen.

Ich weiß nicht, ob er seine eigene Sperre verwendet oder von der Sperre in IronPython abhängig ist.

Ich würde vorschlagen:

a) Run-Tests selbst. Sie sollten in der Lage sein, einen einfachen Test zu schreiben, um zu beweisen, ob es sicher ist oder nicht. Etwas so rohes wie der folgende Code könnte ein guter Anfang sein:

[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) Add Sperren sowieso. Es ist möglicherweise kein großes Problem, die Sperre in Ihrem Code zu aktivieren, und Sie werden die Unsicherheit beseitigen.

Schließlich, wenn die Dokumente sagen, dass etwas nicht Thread-sicher ist, müssen Sie entweder beweisen, dass es ist (Test) oder spielen Sie sicher (Ihr eigenes Sperren). Was auch immer, Multithread-Tests sollten durchgeführt werden, bevor Sie in Produktion gehen. Ich glaube nicht, dass du wirklich Zeit verlierst, wenn du sie am Anfang machst.

Re 2: Wieder ein Vorschlag nur. Erstellen Sie Pool-Threads, die die Initialisierung einmal durchführen und dann diese Threads wiederverwenden.

+2

Ich glaube nicht, dass die Sicherheit von Geweben durch Komponententests verifiziert werden kann. –

+0

@ JeffreyZhao Zustimmen - Thread-Sicherheit ist eine intrinsische Qualität von etwas, kein Unit-Testfall. – data

2

1.

Wenn die Dokumentation von ScriptScope sagt es nicht sicher ist Thread, es glauben oder zumindest handeln, wie Sie glauben. @JimmySchementi hat sich vielleicht die aktuelle Implementierung angeschaut und herausgefunden, dass es derzeit Thread-sicher ist, aber das gibt keine Garantie dafür, wie es sich im nächsten Patch der Klasse verhalten wird, geschweige denn die nächste Hauptversion.

2.

Ja, Sie müssen jede Ihrer ScriptScopes initialisieren. Ich würde versuchen, die Anzahl der benötigten ScriptScopes zu minimieren. Wie das gemacht wird, hängt von Ihrer Einrichtung ab. Wenn der Hauptzweck der betreffenden Threads darin besteht, ein ScriptScope zu hosten, sollten Sie einen ThreadPool verwenden, wobei jeder Thread ein ThreadLocal < ScriptScope> aufweist. Wenn diese Threads andere Dinge tun als Skripts ausführen, sollten Sie einen Objektpool haben, der die ScriptScopes speichert und jeder Thread kann die ScriptScopes auschecken, die Arbeit erledigen und dann das ScriptScope freigeben.

3.

Bevorzugen ThreadLocal über Threadstatic, wenn Sie diesen Weg gehen.