猿问

sys._current_frames() 中的孤立堆栈跟踪

这是一个深奥的纯 Python 问题。

我正在使用sys._current_frames(). 即,我有一个sys._current_frames()每秒运行一次的后台线程,将结果转储到一个文本文件中,然后我有一些 Python 代码可以从最常见到最少对回溯进行排序。

我见过的一个奇怪现象是这样的回溯:

  File "/opt/foo/bar.py", line 1437, in __iter__  
    yield key

yield是我写的生成器。奇怪的是,这个回溯只有一帧。这怎么可能?另一个回溯有很多帧,要么来自进程的顶层,要么来自帧的顶层。这个单帧堆栈跟踪是什么意思?

我的一个理论是,这是生成器的冻结状态,在它产生一个值之后,它正在等待next再次调用它。但我想我用一个单独的实验反驳了这个理论:我做了一个生成器,确保它被暂停,被调用 sys._current_frames(),但我没有看到那种堆栈跟踪。


慕妹3146593
浏览 158回答 1
1回答

交互式爱情

正如sys._current_frames() 文档警告的那样,这对于调试死锁最有用:此功能不需要死锁线程的合作,并且只要它们保持死锁,这些线程的调用堆栈就会被冻结。在调用代码检查帧时,为非死锁线程返回的帧可能与该线程的当前活动无关。sys._current_frames()在您不能保证感兴趣的线程被暂停的任何情况下,自然容易出现竞争条件。正如您所怀疑的,您看到的是暂停生成器的堆栈跟踪。当一个生成器挂起时,它的栈帧没有父帧。它f_back被设置为空。sys._current_frames()检索当前正在运行的线程的堆栈帧,但是当您查看这些帧时,它们可能不再运行了。如果生成器在您调用sys._current_frames()和检查框架之间暂停,这就是它的样子。sys._current_frames()如果它在其他地方恢复,您可能还会在看起来与您实际调用时完全不同的调用堆栈顶部看到它。您的测试没有显示生成器框架,因为您在调用之前sys._current_frames()而不是之后暂停了生成器。生成器的堆栈帧此时不是任何线程的活动帧。
随时随地看视频慕课网APP

相关分类

Python
我要回答