如何在Python中增加堆栈大小

12

我有一个使用自定义DLL的Python程序。这个DLL由于堆栈溢出而崩溃。这种溢出不是由于递归函数出了问题,而是使用alloca()在堆栈上进行大型分配。

我想增加堆栈大小以消除这个错误。是否有任何方法可以做到这一点?


1
如果您可以更改源代码,请参见https://dev59.com/6G445IYBdhLWcg3wDWCc。 - Thomas Ahle
4个回答

10

Python的线程模块允许您为新线程指定一个新的堆栈大小。尝试将其设置为您认为足够大的值,然后在新线程中执行此DLL的工作。


6

如一些相关问题(例如此处)所述,更改堆栈大小以扩展递归深度通常不是一个好主意。但以下代码展示了如何增加堆栈以达到这个目的。在Windows 10 x64系统上使用Python 3.5,它展示了一个非常深的递归,这在正常情况下是不可能的(在我的情况下,通常允许的递归限制似乎为993)。我不知道这个例子需要多大的堆栈,但是在我的机器上,如果只有下面指定的大小的一半,则Python会崩溃。

import sys
import threading

class SomeCallable:
    def __call__(self):
        try:
            self.recurse(99900)
        except RecursionError:
            print("Booh!")
        else:
            print("Hurray!")
    def recurse(self, n):
        if n > 0:
            self.recurse(n-1)

SomeCallable()() # recurse in current thread

# recurse in greedy thread
sys.setrecursionlimit(100000)
threading.stack_size(0x2000000)
t = threading.Thread(target=SomeCallable())
t.start()
t.join()

3

当dll中的函数被执行时,它们无法控制可用的堆栈大小(除非您在库的控制下生成新线程)。

如果dll是自定义的,那么您不可以分配堆而不是栈(或静态分配,如果适用),从而停止问题的发生?


2
据我所知,一个程序只能改变新线程或进程的堆栈大小(例如 Windows 的 CreateThread 函数)。由于 Python(以及 Python 的 Win32 API)没有公开此类功能,因此您应该使用堆内存替换堆栈分配。或者是否有使用堆栈的特定原因?如果您确实需要使用 alloca,则可能需要为 DLL 代码执行创建单独的线程(我认为这是过度设计)。 编辑:更正 - Python 允许在创建新线程时设置堆栈大小(请参见 thread.stack_size

1
ODE引擎(导致问题的DLL)使用alloca来加速大矩阵计算。幸运的是,它有一个编译标志,让我可以切换到malloc。它会稍微慢一点,但它能用。谢谢! - Philippe Beaudoin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接