zoukankan      html  css  js  c++  java
  • 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 '33[31;1m=======蓝牙子线程启动=======33[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 '33[32;1m=======Zigbee子线程启动=======33[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 '33[33;1m===BYEBYE====33[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

  • 相关阅读:
    An exception was thrown while activating Castle.Proxies.PersonAppServiceProxy. ABP Netcore
    abp 深坑三 Unable to cast object of type 'System.Double' to type 'System.Single'.System.InvalidCastException: Unable to cast object of type 'System.Double' to type 'System.Single'.
    《统计学习方法》笔记--奇异值分解
    《统计学习方法》笔记--聚类方法
    《统计学习方法》笔记--条件随机场
    《统计学习方法》笔记--EM算法
    统计学习方法》笔记--提升方法(二)
    《统计学习方法》笔记--提升方法
    《统计学习方法》笔记--决策树
    《统计学习方法》笔记--逻辑回归
  • 原文地址:https://www.cnblogs.com/webber1992/p/6287644.html
Copyright © 2011-2022 走看看