轉載請註明出處:https://blog.csdn.net/jinixin/article/details/80384729
本文是信號機制三篇記錄中的第三篇,介紹信號機制的一個小用法,定位hang住代碼的位置。第一篇簡單介紹了Linux信號機制,第二篇介紹Python中負責信號處理的signal模塊,並給出了小demo。三篇組成一個系列,想起拋磚引玉的作用,希望對大家能有所幫助。
問題
想必大家在工作中可能遇到過這樣的問題,調試和執行程序都沒有問題,但在運行一段時間後,程序莫名阻塞在某處。
發生這種問題,第一反應就是頭疼,茫茫碼海,該如何去定位問題呢?
這時我會想通過增加日誌尋找在哪處進入無限循環或是hang住了,但除非一次性加入很多日誌,否則無法準確定位問題點。而一次無法定位,我只好等到第二次hang住後,針對日誌反饋再繼續對可疑區域增加記錄,如此往復。結果服務可靠性沒有了保證,而且整個人也十分受挫。
那有沒有什麼辦法可以一下子就找到問題在哪?不打那麼多沒用的日誌,不用使服務多次停止呢?
思路
這裏暫且給出一種思路,做個拋磚引玉。
在程序中加入信號量機制,當程序運行一段時間hang住後,直接對進程發送對應信號量,使程序轉入處理特定信號量的函數中,在此函數中打印目前程序運行的上下文內容,便可大致定位問題所在。
案例
下面就給出一個Python演示程序:
#!/usr/bin/env python3
# coding=utf-8
import os
import time
import signal
import traceback
def handle_SIGINT(signum, frame):
print('handle sigint!{0}{1}'.format(os.linesep, '*' * 100))
print(os.linesep.join(traceback.format_stack(frame))) # 打印收到SIGINT信號時,程序執行處的上下文信息
def main():
signal.signal(signal.SIGINT, handle_SIGINT) # 註冊SIGINT信號的處理器爲handle_SIGINT函數
while True:
print('呀咿呀,你仰起臉,笑得香滿月')
time.sleep(60)
if __name__ == '__main__':
main()
發現程序hang住後,向對應進程發送SIGINT信號:
程序收到SIGINT信號後,進入對應處理器,打印此時運行的上下文:
這時通過打印的上下文便可大致定位問題所在
文中如有不當之處,還望包容和指出,感謝~