「信號機制」應用—程序hang住怎麼辦

轉載請註明出處: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信號後,進入對應處理器,打印此時運行的上下文:

 

這時通過打印的上下文便可大致定位問題所在

 

文中如有不當之處,還望包容和指出,感謝~

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章