python threading模塊中對於信號的抓取


最近的物聯網智能網關(樹莓派)項目中遇到這樣一個問題:要從多個底層串口讀取發來的數據,並且做出相應的處理,對於每個串口的數據的讀取我能想到的可以采用兩種方式:

一種是采用輪詢串口的方式,例如每3s向每個串口的buffer區去取一次數據,但是這樣可能會有緩沖區溢出的可能,同時,數據的同步也可能會出現一定的問題,因為數據的上傳周期是可以用戶自定義的,一旦用戶定義的上傳周期過短或過長,都可能造成讀取的數據出問題。

另一種方式,就是采用多線程方式,把每個串口讀取數據放在單獨的子線程中,每個子線程阻塞於串口讀,后來在測試時發現,由於python的threading模塊沒有實現對信號的處理,所以當父線程阻塞時,我們需要安裝一個信號處理函數,例如,抓取一個Ctrl+C的SIGINT信號的抓取,以方便我們測試程序的退出。下面記錄下遇到的坑:

1、在多線程中,首先要把所有的子線程在start之前設置為daemon;

2、如果父線程調用.join()方法實現對自身的阻塞,那么父線程將永遠都抓不到目標信號,因此應該要使用isAlive()方法模擬父線程阻塞,然后不斷輪詢子線程的運行狀況;

3、完成對於sig_handler()函數的處理。

 

實現代碼如下:

def blue_thread():
    ser_blue = serial.Serial("/dev/ttyUSB0", 9600)  # 藍牙串口
    print '\033[31;1m=======藍牙子線程啟動=======\033[0m'
    while ser_blue.isOpen():
        count = ser_blue.inWaiting()
        if count != 0:
            recv = ser_blue.read(count)
            print recv
            # str_handle(recv)
        time.sleep(1)
    ser_blue.close()

def zigbee_thread():
    ser_zigbee = serial.Serial("/dev/ttyS0", 115200)  # zigbee串口
    print '\033[32;1m=======Zigbee子線程啟動=======\033[0m'
    while ser_zigbee.isOpen():
        count = ser_zigbee.inWaiting()
        if count != 0:
            recv = ser_zigbee.read(count)
            print recv
            # str_handle(recv)
        time.sleep(1)
    ser_zigbee.close()

def signal_handler(num,frame):
    print '\033[33;1m===BYEBYE====\033[0m'
    sys.exit(0)

def main():
# 由於python的多線程模塊沒有實現對信號的處理,所以父線程阻塞,我們需要安裝一個信號處理函數,能讓我們方便退出程序,並且要把子線程設為daemon
    signal.signal(signal.SIGINT,signal_handler)

    threads = []
    threads.append(threading.Thread(target=blue_thread,args=()))
    threads.append(threading.Thread(target=zigbee_thread,args=()))
    for t in threads:
        t.setDaemon(True)
        t.start()
#    t.join()
# 不能使用join,要使用isAlive方法模擬父線程阻塞,不斷輪詢子線程的運行狀況
    while True:
        alive = False
        for t in threads:
            alive = alive or t.isAlive()
            if alive == True:
                break
        if not alive:
            break

if __name__ == "__main__":

    main()

 

以上處理方法靈感源自:http://www.jb51.net/article/35165.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM