Python readlines Api 从串口访问需要很长时间
Python readlines Api takes long time while accessing from serial port
我有 12 个串行设备连接到我的 PC,从设备读取一个值需要将近 4 秒,下面的代码片段总共需要大约 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
探查器结果:
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}
谢谢,
罗斯
如果设备是独立的;您可以同时阅读他们的回复:
#!/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()
吗?您应该读取单行还是固定数量的字节反而?)。对于普通的 file/pipe,.readlines()
将读取所有数据直到 EOF。检查它是否对串行设备有意义。
我有 12 个串行设备连接到我的 PC,从设备读取一个值需要将近 4 秒,下面的代码片段总共需要大约 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
探查器结果:
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}
谢谢, 罗斯
如果设备是独立的;您可以同时阅读他们的回复:
#!/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()
吗?您应该读取单行还是固定数量的字节反而?)。对于普通的 file/pipe,.readlines()
将读取所有数据直到 EOF。检查它是否对串行设备有意义。