博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python threading模块中对于信号的抓取
阅读量:6272 次
发布时间:2019-06-22

本文共 2047 字,大约阅读时间需要 6 分钟。

最近的物联网智能网关(树莓派)项目中遇到这样一个问题:要从多个底层串口读取发来的数据,并且做出相应的处理,对于每个串口的数据的读取我能想到的可以采用两种方式:

一种是采用轮询串口的方式,例如每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:            breakif __name__ == "__main__":    main()

 

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

转载于:https://www.cnblogs.com/webber1992/p/6287644.html

你可能感兴趣的文章
linux学习笔记一----------文件相关操作
查看>>
Mono for Android 优势与劣势
查看>>
服务器端开发技术
查看>>
Python3中urllib详细使用方法(header,代理,超时,认证,异常处理)
查看>>
ajax提交多个对象,使用序列化表单和FormData
查看>>
深入分析由前序和中序重构二叉树问题
查看>>
leetcode 题解 || Valid Parentheses 问题
查看>>
将图片转成base64字符串并在JSP页面显示的Java代码
查看>>
什么是WeakHashMap--转
查看>>
js 面试题
查看>>
第二十二节,三元运算
查看>>
Yacc 与 Lex 快速入门
查看>>
Unity中HDR外发光的使用
查看>>
Flume负载均衡配置
查看>>
Ajax详解
查看>>
Ubuntu C/C++开发环境的安装和配置
查看>>
百世汇通快递地区选择插件,单独剥离
查看>>
Linux系统调用---同步IO: sync、fsync与fdatasync【转】
查看>>
【MyBatis学习06】输入映射和输出映射
查看>>
[LeetCode] Decode String 解码字符串
查看>>