gpt4 book ai didi

python在线程中的exec脚本中中断无限循环

转载 作者:太空宇宙 更新时间:2023-11-04 03:43:04 25 4
gpt4 key购买 nike

GUI 应用程序允许用户编写 Python 脚本,然后运行它(通过 exec)。问题是如果用户错误(我不关心恶意,只是用户的诚实编码错误)脚本包含无限循环,控制将永远不会返回到我的应用程序。由于 GUI,键盘中断不起作用。

我已经确定了四种处理方法:

  1. 跟踪:使用 sys.settrace 以便在每一行调用一个函数;在那里,我可以放置逻辑来尝试确定同一段代码是否正在一遍又一遍地执行(我还不知道这在实践中会有多大的挑战性)。我猜这可能会大大降低执行速度。
  2. 异步异常:在单独的线程中运行脚本,并使用 ctypes 让主线程使用 PyThreadState_SetAsyncExc 在脚本线程中引发异常以将其踢出循环(参见 https://gist.github.com/liuw/2407154http://tomerfiliba.com/recipes/Thread2/ )。然后调用 exec 的线程部分将恢复控制并可以采取适当的操作(向用户显示消息等)。我知道,不应从外部中止线程,但在这里,即使这样做会使脚本更改的对象处于未定义状态,至少它会允许 GUI 丢弃不再可靠的对象(它可以做到这一点,因为脚本可访问的所有修改都在一个大对象中,可以将其丢弃并从磁盘重新加载)。
  3. Separate process:使用 multiprocessing 模块,将在单独的进程中运行脚本;然而,脚本可以包含对存在于父线程主线程中的对象的调用,因此这将变得非常复杂。
  4. 守护线程:在守护线程中运行脚本,然后如果脚本在一段时间后没有返回,则认为它“挂起”。当应用程序退出时,线程将继续运行,用户可以通过任务管理器强制终止它(或者退出的线程可以,通过引发 SystemException 等)。

那么问题来了:如果我必须提供此功能,那么以上方法中哪一种是万恶之轻?除了上述 4 种之外,还有其他技术吗?

最佳答案

一种方法是使用自定义 multiprocessing.Manager 对象。它可以为您处理同步。 (链接:multiprocessing)

这是一个拥有单个实例的示例,多进程进程能够在其上调用方法。注意我没有使用实例状态,这留给读者:)

原始代码将“maths.add”(实例方法)传递给池,但方法不可挑选。因此,我创建了全局“my_add”,它接受一个数学实例(可选取的),然后将一些数字加在一起并得出结果。

来源

from multiprocessing import Pool
from multiprocessing.managers import BaseManager

class MathsClass(object):
def add(self, x, y):
return x + y
def mul(self, x, y):
return x * y

class MyManager(BaseManager):
pass

MyManager.register('Maths', MathsClass)

def my_add(mobj, *args):
return mobj.add(*args)

if __name__ == '__main__':
manager = MyManager()
manager.start()
maths = manager.Maths()

# pass the shared 'maths' object into each process

pool = Pool()
print pool.apply(my_add, [maths, 4, 3])
# print maths.add(4, 3) # prints 7
print pool.apply(my_add, [maths, 7, 8])
# print maths.mul(7, 8) # prints 56

输出

7
15

关于python在线程中的exec脚本中中断无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25365471/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com