這是一個深奧的純 Python 問題。我正在使用sys._current_frames(). 即,我有一個sys._current_frames()每秒運行一次的后臺線程,將結果轉儲到一個文本文件中,然后我有一些 Python 代碼可以從最常見到最少對回溯進行排序。我見過的一個奇怪現象是這樣的回溯: File "/opt/foo/bar.py", line 1437, in __iter__
yield key這yield是我寫的生成器。奇怪的是,這個回溯只有一幀。這怎么可能?另一個回溯有很多幀,要么來自進程的頂層,要么來自幀的頂層。這個單幀堆棧跟蹤是什么意思?我的一個理論是,這是生成器的凍結狀態,在它產生一個值之后,它正在等待next再次調用它。但我想我用一個單獨的實驗反駁了這個理論:我做了一個生成器,確保它被暫停,被調用 sys._current_frames(),但我沒有看到那種堆棧跟蹤。
1 回答

交互式愛情
TA貢獻1712條經驗 獲得超3個贊
正如sys._current_frames()
文檔警告的那樣,
這對于調試死鎖最有用:此功能不需要死鎖線程的合作,并且只要它們保持死鎖,這些線程的調用堆棧就會被凍結。在調用代碼檢查幀時,為非死鎖線程返回的幀可能與該線程的當前活動無關。
sys._current_frames()
在您不能保證感興趣的線程被暫停的任何情況下,自然容易出現競爭條件。
正如您所懷疑的,您看到的是暫停生成器的堆棧跟蹤。當一個生成器掛起時,它的棧幀沒有父幀。它f_back
被設置為空。
sys._current_frames()
檢索當前正在運行的線程的堆棧幀,但是當您查看這些幀時,它們可能不再運行了。如果生成器在您調用sys._current_frames()
和檢查框架之間暫停,這就是它的樣子。sys._current_frames()
如果它在其他地方恢復,您可能還會在看起來與您實際調用時完全不同的調用堆棧頂部看到它。
您的測試沒有顯示生成器框架,因為您在調用之前sys._current_frames()
而不是之后暫停了生成器。生成器的堆棧幀此時不是任何線程的活動幀。
添加回答
舉報
0/150
提交
取消