Python readlines Api从串口访问时需要很长时间
Posted
技术标签:
【中文标题】Python readlines Api从串口访问时需要很长时间【英文标题】:Python readlines Api takes long time while accessing from serial port 【发布时间】:2015-07-07 15:45:56 【问题描述】:我有 12 个串行设备连接到我的 PC,要从设备中读取一个值大约需要 4 秒,而下面的 sn-p 总共需要大约 1 分钟来读取所有值。他们是一种优化以下 python 脚本或使用其他 API 的方法,这可以花费更少的时间来串行访问设备和读取值
代码片段:
if sys.platform.startswith('linux'):
for sfiles in glob.glob('/dev/serial/by-id/usb-XXXXdevNAME*'):
try:
s = serial.Serial(sfiles, 9600, timeout=2)
s.write('XXXdeviceCommandToReadValue XXXX\r\n')
response = s.readlines() // from the profiles it looks readlines is using more time
Profiler 结果:
16309 function calls (16306 primitive calls) in 54.605 seconds Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.001 0.001 54.605 54.605 /opt/lnx_attenTool/att_devices.py:49(scan_devices)
12 0.009 0.001 54.522 4.543 method 'readlines' of '_io._IOBase' objects
2136 0.020 0.000 54.513 0.026 /usr/lib/python2.7/dist-packages/serial/serialposix.py:439(read)
2136 54.482 0.026 54.482 0.026 select.select
24 0.000 0.000 0.072 0.003 /usr/lib/python2.7/dist-packages/serial/serialposix.py:419(close)
12 0.072 0.006 0.072 0.006 posix.close
2112 0.007 0.000 0.007 0.000 posix.read
12 0.001 0.000 0.007 0.001 /usr/lib/python2.7/dist-packages/serial/serialutil.py:213(__init__)
12 0.000 0.000 0.005 0.000 /usr/lib/python2.7/dist-packages/serial/serialposix.py:265(open)
12 0.004 0.000 0.004 0.000 posix.open
2112 0.002 0.000 0.002 0.000 method 'extend' of 'bytearray' objects
1 0.000 0.000 0.002 0.002 /usr/lib/python2.7/glob.py:18(glob)
13 0.000 0.000 0.002 0.000 /usr/lib/python2.7/glob.py:29(iglob)
6523/6522 0.002 0.000 0.002 0.000 len
1 0.000 0.000 0.002 0.002 /usr/lib/python2.7/glob.py:66(glob1)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/fnmatch.py:45(filter)
12 0.001 0.000 0.001 0.000 /usr/lib/python2.7/dist-packages/serial/serialposix.py:297(_reconfigurePort)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/re.py:188(compile)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/re.py:226(_compile)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/sre_compile.py:493(compile)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/sre_parse.py:675(parse)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/sre_parse.py:301(_parse_sub)
1 0.000 0.000 0.001 0.001 /usr/lib/python2.7/sre_parse.py:379(_parse)
12 0.000 0.000 0.000 0.000 /usr/lib/python2.7/dist-packages/serial/serialposix.py:464(write)
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/sre_compile.py:478(_code)
12 0.000 0.000 0.000 0.000 posix.readlink
谢谢, 罗希特
【问题讨论】:
你分析过这段代码吗?你确定这就是减速的地方吗?我有一种感觉,读/写文件操作是减速的地方,而不是从设备中获取价值。 不,我没有进行分析,也不确定读/写操作。但是在使用腻子时,我没有看到发出设备命令的任何延迟 好吧,我建议看看this 来确定减速而不是仅仅猜测。 这是分析器结果:ncalls tottime percall cumtime percall filename:lineno(function) 1 0.001 0.001 54.605 54.605 /opt/lnx_attenTool/att_devices.py:49(scan_devices) 12 0.009 0.001 54.522 4.543 meth '_io._IOBase' 对象的'readlines' 2136 0.020 0.000 54.513 0.026 /usr/lib/python2.7/dist-packages/serial/serialposix.py:439(读取) 我投票结束这个问题,因为它应该被迁移到Code Review 【参考方案1】:如果设备是独立的;您可以同时阅读他们的回复:
#!/usr/bin/env python
from glob import glob
from multiprocessing.pool import ThreadPool
import serial
def get_response(path):
try:
s = serial.Serial(path, 9600, timeout=2)
s.write('XXXdeviceCommandToReadValue XXXX\r\n')
return path, s.readlines(), None
except Exception as e:
return path, None, e
paths = glob('/dev/serial/by-id/usb-XXXXdevNAME*')
results = ThreadPool(min(len(paths), 20)).imap_unordered(get_response, paths)
for path, lines, error in results:
print(path, lines, error) # handle results here
假设大部分时间都花在 I/O 上,代码应该会更快完成。
此外,请调查s.readlines()
在这种情况下是否是正确的 API 用法(在它之前是否需要 s.flush()
?您应该读取单行还是固定数量的字节?)。对于普通文件/管道,.readlines()
将读取所有数据,直到 EOF。检查它是否对串行设备有意义。
【讨论】:
以上是关于Python readlines Api从串口访问时需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章