在Python脚本中设置堆栈大小

47

我正在将一个csh脚本转换为Python脚本。该脚本调用一个内存密集型的可执行文件,需要一个非常大的堆栈,因此csh脚本将stacksize设置为无限制:

limit stacksize unlimited

当我尝试在Python中重现此脚本时,我使用非常原始的方式来执行它们,使用os.system,例如:

os.system('some_executable')

但我不知道如何告诉操作系统以无限制的堆栈大小运行这些可执行文件。有没有一种方法可以在Python脚本中指定调用的堆栈大小? 是否有某个低级系统调用应该使用? 是否有一个控制此功能的模块(类似于shutil)?


尝试在Stack Clash修复之后设置rlimit_stack可能会导致失败或相关问题。还请参阅Red Hat Issue 1463241 - jww
4个回答

51

我对以下代码有良好的经验。它不需要任何特殊的用户权限:

import resource, sys
resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**6)

但是似乎不能在pypy上工作。

如果resource.setrlimit不起作用,您也可以尝试使用线程:

sys.setrecursionlimit(10**6)
import threading
threading.stack_size(2**26)
threading.Thread(target=main).start()

7
如果堆栈溢出,sys.setrecursionlimit(10 ** 6)会导致Python解释器崩溃。 - Wilfred Hughes
7
请注意,截至目前,资源模块不适用于Windows操作系统。 - ofer.sheffer
@ofer.sheffer 这仍然比使用 os.system 的被接受的答案要好。 - Thomas Ahle
1
@ThomasAhle 我遇到了“没有名为 resource 的模块”的错误。 - garg10may
尝试安装它。我有资源模块。 - Szymon Roziewski
3
@ThomasAhle ,-1代表什么?你是不是想用resource.RLIM_INFINITY - user3064538

21

如果你想要的话,可以直接使用你的shell的(u)limit命令:

os.system('ulimit -s unlimited; some_executable')

或者(可能更好的方法)使用resource.setrlimit

resource.setrlimit(resource.RLIMIT_STACK, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))

1
第一个选项对我不起作用;我相信这是因为os.system在基本shell sh中执行命令,而不是bash或tcsh。但你的第二个选项正是我需要的,谢谢。 (我无法确定谁首先建议“setrlimit”,所以我授予此选项,因为它包括显式代码。虽然我很感激大家的答案)。 - marshall.ward
1
是的,我应该提到 - 有些 shell 使用 limit,有些使用 ulimit,有些允许两者;明确调用是一个更好的主意。 - Nicholas Riley

13
你需要使用Python中的setrlimit接口,其中包括resource.RLIMIT_STACK
请注意,标准用户不能提高其硬限制,只有具有CAP_SYS_RESOURCE能力(请参见capabilities(7))的进程才能提高其限制;因此,您可能需要使用PAM pam_limits(8)limits.conf(5)文件来提高相关用户的硬限制。

4

您可以通过threading.stack_size()修改当前进程的堆栈大小,但我不确定子进程是否会正确继承。该接口还需要指定堆栈大小,“无限制”不是一个选项。


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