我正在PyQt开发一个应用程序(主要是Windows,但未来打算去多平台),它专注于处理某些数字数据,所以核心基本上是围绕numpy数组和matplotlib图表构建的。不过,我想让系统的一部分Python脚本化,允许用户稍微调整数据处理。他们编写的脚本代码存储在一个字符串中,只需要传入和传出一些arbirtary类型的参数。并添加一些错误处理,以及...这可以以非常简单的方式在Python代码片段在这里实现,如:控制PyQt中的异步线程 - 多线程或多处理?
global_dict = {} # values could go in here
local_dict = {} # values could go in here
try:
exec(script_code, global_dict, local_dict)
value = local_dict[variable_name] # value out
#etc...
的问题是,用户脚本是在我的掌握中,用户可以编写他们喜欢的任何内容,并且可以花费大量时间执行可能会冻结GUI的内容。所以我需要去多线程。我已经有一个工作解决方案。我使用从QtCore.QRunnable运行继承的类和上面的代码异步。它工作正常,并在脚本完成时正确通知GUI线程,传递结果并销毁线程。但我仍然有三个严重的问题:
1)一个关键问题:如何中止脚本执行?尽管异步脚本不会冻结GUI,但它可能非常长或甚至无限。用户当然必须有选择放弃执行而不必终止整个应用程序。这对于QRunnable来说似乎不可行。所以我想到了从QRunnable切换到已终止方法的QThread。但严格不建议使用此方法。应用程序如何从其一个线程的终止中恢复,这是非常令人怀疑的,例如,在传入脚本的对象引用计数时会发生什么情况。这个问题甚至可以解决吗?我不知道......也许有一个我看不到的神奇解决方案。 Python多处理模块可以提供帮助吗?
2)一个重要的问题:由于用户可以通过脚本传入和传出数据,这是通过引用完成的,他们也可以更改数据。在Python多线程中,GIL确保没有两个线程同时写入相同的数据,但可能发生数据已被处理或显示在应用程序的另一部分中。所以我需要将脚本输入写入脚本,当用户尝试写入时抛出异常。它甚至有可能吗?
3)一个不错的解决方案,但它可以生存的问题:有时几个脚本可以同时执行。由于Python的GIL,所有线程仅在一个解释器和一个处理器内核中执行。这可能是性能的限制。据我了解,为了从多处理器内核中受益,我需要从多线程切换到多处理。但如何在给定的情况下做到这一点?它是否与PyQt架构兼容?如何传入和传出值?如何终止?
也许我问得太多了,也许我的愿望不是来自这个现实。不过,我会非常感谢任何暗示或建议或资料来源。
也许我已经找到了解决方案,至少我的问题... killable线程的一部分:[链接](http://tomerfiliba.com/recipes/Thread2/)...我要测试它。 –
为什么这会得到downvoted?意见? – neuronet