如何从 Linux 上当前运行的 Python 进程访问数据结构?
Posted
技术标签:
【中文标题】如何从 Linux 上当前运行的 Python 进程访问数据结构?【英文标题】:How to access a data structure from a currently running Python process on Linux? 【发布时间】:2011-04-20 15:39:39 【问题描述】:我有一个长期运行的 Python 进程,它生成的数据比我计划的要多。我的结果存储在一个列表中,该列表将在程序完成时被序列化(腌制)并写入磁盘 - 如果它达到那么远。但是按照这个速度,列表更有可能耗尽所有 1+ GB 的可用 RAM,并且进程会崩溃,从而丢失我在进程中的所有结果。
我计划修改我的脚本以定期将结果写入磁盘,但如果可能的话,我想保存当前正在运行的进程的结果。有什么方法可以从正在运行的进程中获取内存中的数据结构并将其写入磁盘?
我找到了 code.interact(),但由于我的代码中还没有这个钩子,它对我来说似乎没有用 (Method to peek at a Python program running right now)。
我在 Fedora 8 上运行 Python 2.5。有什么想法吗?
非常感谢。
沙欣
【问题讨论】:
你希望用'当前进程的数据结构'做什么?如果您将其保存并重新加载,您会不会像开始时一样内存不足? 在这种特殊情况下,我会将其传输到另一台机器(具有更多内存)以对其进行反序列化,然后将其逐个写回或直接加载到数据库中。显然不可持续,但我只是在这里寻找一种一次性的权宜之计。 【参考方案1】:对于正在运行的程序,您无能为力。我唯一能想到的就是附加 gdb 调试器,停止进程并检查内存。或者,确保您的系统设置为保存核心转储,然后使用kill --sigsegv <pid>
终止该进程。然后,您应该能够使用 gdb 打开核心转储并在闲暇时对其进行检查。
有一些 gdb 宏可以让您检查 python 数据结构并从 gdb 中执行 python 代码,但要使这些宏工作,您需要启用调试符号编译 python,我怀疑这是您的情况。首先创建核心转储然后使用符号重新编译 python 将不起作用,因为所有地址都将从转储中的值更改。
以下是一些从 gdb 内省 python 的链接:
http://wiki.python.org/moin/DebuggingWithGdb
http://chrismiles.livejournal.com/20226.html
或谷歌搜索'python gdb'
注意设置 linux 以创建 coredumps 使用 ulimit 命令。
ulimit -a
将向您显示当前设置的限制。
ulimit -c unlimited
将启用任何大小的核心转储。
【讨论】:
太糟糕了。不过,这听起来更普遍,所以我会试一试。感谢您的详细回复。【参考方案2】:虽然肯定不是很漂亮,但您可以尝试通过 proc 文件系统访问您的进程数据.. /proc/[pid-of-your-process]。 proc 文件系统存储了大量每个进程的信息,例如当前打开的文件指针、内存映射等等。通过一些挖掘,您可能能够访问您需要的数据。
我仍然怀疑您应该从 python 中查看这个并进行一些运行时日志记录和调试。
【讨论】:
【参考方案3】:+1 非常有趣的问题。
我不知道这对你有多好(特别是因为我不知道你是否会在程序中重用腌制列表),但我建议这样做:当你写入磁盘时,打印出来STDOUT 的列表。当你运行你的 python 脚本(我猜也是从命令行)时,将输出重定向到附加到这样的文件中:
python myScript.py >> logFile.
这应该将所有列表存储在 logFile 中。 这样,您始终可以查看 logFile 中的内容,并且您应该在其中拥有最新的数据结构(取决于您调用 print 的位置)。
希望对你有帮助
【讨论】:
【参考方案4】:This answer 有关于将gdb
附加到python 进程的信息,使用宏可以让你进入该进程中的pdb
会话。我自己没有尝试过,但它得到了 20 票。听起来您可能最终会挂起应用程序,但在您的情况下似乎也值得冒险。
【讨论】:
以上是关于如何从 Linux 上当前运行的 Python 进程访问数据结构?的主要内容,如果未能解决你的问题,请参考以下文章