简体   繁体   English

IronPython中的多线程

[英]Multi-threading in IronPython

I have a "script class" in IronPython, and scripting in my app works by calling methods on its instance. 我在IronPython中有一个“脚本类”,我的应用程序中的脚本通过调用其实例上的方法来工作。 I need to implement calling scripts from multiple threads. 我需要从多个线程实现调用脚本。 What is the correct way to do it? 这样做的正确方法是什么?

I have multiple concerns: 我有多个问题:

  1. Is ScriptScope thread-safe? ScriptScope是线程安全的吗? Information is contradictory. 信息是矛盾的。 ScriptScope's documentation says : "ScriptScope is not thread safe. Host should either lock when multiple threads could access the same module or should make a copy for each thread." ScriptScope的文档说“ScriptScope不是线程安全的。当多个线程可以访问同一个模块或者应该为每个线程复制时,主机应该锁定。” However, IronRuby uses the same DLR and @JimmySchementi says that "ScriptRuntime, ScriptEngine, and ScriptScope are all thread safe, designed to be used between threads. Specifically, ScriptScope uses a thread-safe data-store, so ScriptScope can be shared between threads." 但是,IronRuby使用相同的DLR和@JimmySchementi说 “ScriptRuntime,ScriptEngine和ScriptScope都是线程安全的,设计用于线程之间。具体来说,ScriptScope使用线程安全的数据存储,因此ScriptScope可以在线程之间共享“。

  2. If I create multiple ScriptScope s, that would mean executing the same initialization script multiple times. 如果我创建多个ScriptScope ,那将意味着多次执行相同的初始化脚本。 Let's suppose that I run ten Python script files, import five assemblies and on the whole execute quite a bit of code to get the "script object" ready. 假设我运行了10个Python脚本文件,导入了5个程序集,并且总体上执行了相当多的代码以使“脚本对象”准备就绪。 Is there any way to avoid the time and memory cost of running a lot of the same code for each and every thread? 有没有办法避免为每个线程运行大量相同代码的时间和内存成本?

  3. Is making the ScriptScope variable thread-static (that is, applying ThreadStaticAttribute ) and executing initialization for every thread which is utilized by Task.Run the way to go? 是使ScriptScope变量线程静态(即应用ThreadStaticAttribute )并为Task.Run使用的每个线程执行初始化的方式去? Or should I use a TaskScheduler with a limit on concurrency, because the cost of multiple scopes is high? 或者我应该使用具有并发限制的TaskScheduler ,因为多个范围的成本很高?

On the whole: how to correctly implement running the same script on different arguments in multiple threads? 总的来说: 如何正确实现在多个线程中的不同参数上运行相同的脚本? Scripts must be executing simultaneously and must not crash due to race conditions. 脚本必须同时执行,并且不得因竞争条件而崩溃。

1. 1。

If the documentation of ScriptScope says it is not thread safe, believe it, or at least act like you believe it. 如果ScriptScope的文档说它不是线程安全的,请相信它,或者至少表现得像你相信它。 @JimmySchementi may have looked at the current implementation and worked out that it is currently thread safe, but this give no guarantees about how it will behave in the next patch of the class, let alone the next major release. @JimmySchementi可能已经查看了当前的实现,并确定它当前是线程安全的,但是这并不保证它在下一个类的补丁中会如何表现,更不用说下一个主要版本了。

2. 2。

Yes you will need to initialise each of your ScriptScopes. 是的,您需要初始化每个ScriptScope。 I would try and minimise the number of ScriptScopes you require, how to do this will depend on your set up. 我会尽量减少你需要的ScriptScope数量,如何做到这一点取决于你的设置。 If the main purpose of the threads concerned is to host a ScriptScope then you should use a ThreadPool with each thread having one ThreadLocal<ScriptScope>. 如果相关线程的主要目的是托管ScriptScope,那么你应该使用ThreadPool,每个线程都有一个ThreadLocal <ScriptScope>。 If these threads are doing other things as well as running scripts then you should have an Object pool storing the ScriptScopes and each thread can checkout the ScriptScopes, do the work, then release the ScriptScope. 如果这些线程正在执行其他操作以及运行脚本,那么您应该有一个存储ScriptScopes的对象池,每个线程都可以检出ScriptScopes,完成工作,然后释放ScriptScope。

3. 3。

Prefer ThreadLocal over ThreadStatic if you go down this path. 如果沿着这条路走下去,首选ThreadLocal而不是ThreadStatic。

This is how you do It in scripts, If I understood you correctly. 这就是你在脚本中的表现,如果我理解正确的话。

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

See what that script does, It completely launches a new thread of the same thing, with different arguments. 看看那个脚本做了什么,它完全启动了一个具有不同参数的同一个东西的新线程。

The py file you can see if FULLY threaded, and uses IronPython. py文件你可以看到FULLY线程,并使用IronPython。 That is HOW you correctly do threads, and NOT in any other way. 那就是你如何正确地做线程,而不是以任何其他方式。

Since, it doesn't look like you are getting a concrete answer I have a general one. 因为,看起来你得到一个具体的答案,我有一个普遍的答案。

A colleague of mine used IronPhython in my previous job and handling multithreading would have been essential, so I can say that it is possible to run IronPython in a multithreaded environment on a production system. 我的一位同事在我以前的工作中使用过IronPhython并且处理多线程是必不可少的,所以我可以说在生产系统上的多线程环境中运行IronPython是可能的。

I don't know if he used his own locking or depended on the locking inside IronPython. 我不知道他是否使用了自己的锁定或依赖于IronPython中的锁定。

I'd suggest: 我建议:

a) Run tests yourself. a)自己运行测试。 You should be able to write a simple test to prove if it's safe or not. 您应该能够编写一个简单的测试来证明它是否安全。 Something as crude as the following code could be a good start: 像下面的代码一样原始的东西可能是一个好的开始:

    [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 locks anyway. b)无论如何添加锁。 It may not be a big issue to have locking done in your code and you will remove the uncertainty. 在您的代码中完成锁定可能不是一个大问题,您将消除不确定性。

Ultimately if the docs say something is not thread-safe you will have to either prove it is (test) or play safe (your own locking). 最终,如果文档说某些东西不是线程安全的,你将不得不证明它是(测试)或安全(你自己的锁定)。 No matter what, having multithreaded tests should be done before you go into production anyway. 无论如何,在你投入生产之前应该进行多线程测试。 I don't think you really loose any time by doing them at the beginning. 我不认为你在开始的时候做任何时候都不会放松。

Re 2: Again a suggestion only. 回复2:再次提出建议。 Create a pool threads which do initialization once and then reuse these threads. 创建一个初始化一次的池线程,然后重用这些线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM