Python Pyserial и использование разгруженного процессора - PullRequest
0 голосов
/ 09 февраля 2012

MacOS 10.7.3, python 2.5

Я использую pyserial, чтобы открыть соединение с внешним сервером. Соединение открывается как:

HOST = '10.0.0.1'
PORT = '16010'
theURL = 'socket://' + HOST + ':' + PORT
conn = serial.serial_for_url(theURL, baudrate=115200)
conn.timeout = 2

и тогда чтение выглядит так:

try:
    while len(rawData) == 0 and self.shutdown == False:
        rawData = conn.readline()
except:
    some error handling code...

Проблема в том, что если я убью сервер на 10.0.0.1:16010, код продолжит работать, но загрузка процессора возрастет до 100%. Ошибка не выдается, поэтому исключение никогда не вводится.

Это похоже на проблему в pyserial, но, возможно, кто-то здесь сталкивался с этим раньше и знает, как обнаружить потерянное соединение, чтобы можно было корректно обработать ситуацию.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 01 марта 2016

Тот факт, что использование вашего ЦП привязано, вероятно, указывает на то, что вызов readline не блокируется по таймауту, а мгновенно возвращается.Поэтому, если ваш обычный тайм-аут равен 2, вы можете использовать:

from time import time

try:
    while len(rawData) == 0 and self.shutdown == False:
        before = time()  
        rawData = conn.readline()
        if (len(rawData)==0) and ((time()-before)<2):
              raise Exception("Early readline return.")
except:
    some error handling code...
0 голосов
/ 21 мая 2019

Очень хорошее решение для этого можно найти здесь :

class ReadLine:
    def __init__(self, s):
        self.buf = bytearray()
        self.s = s

    def readline(self):
        i = self.buf.find(b"\n")
        if i >= 0:
            r = self.buf[:i+1]
            self.buf = self.buf[i+1:]
            return r
        while True:
            i = max(1, min(2048, self.s.in_waiting))
            data = self.s.read(i)
            i = data.find(b"\n")
            if i >= 0:
                r = self.buf + data[:i+1]
                self.buf[0:] = data[i+1:]
                return r
            else:
                self.buf.extend(data)

ser = serial.Serial('COM7', 9600)
rl = ReadLine(ser)

while True:

    print(rl.readline())
0 голосов
/ 09 февраля 2012

Если вы не зависите от .readline(), вы можете сделать это так:

self.plugin.conn = Serial(..., timeout = 1)
...
if not self.shutdown:
    rawData = self.plugin.conn.read(1)
    if rawData:
        rawData += self.plugin.conn.read(self.plugin.conn.inWaiting())
    else:
        raise Exception("timeout")

Я не уверен, правильно ли я понял ваше намерение, поэтому вам, возможно, придется подстроиться ...

...