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。检查它是否对串行设备有意义。