3

このアドバイスに従って、シリアル通信を実装しようとしています。

基本的に、ポートをリッスンしてブロックし、完全な行が受信されると、それをグローバルキューにプッシュする別のスレッドを作成します。

ただし、ドキュメントのこの警告は私を混乱させます。

readlines() はタイムアウトでのみ機能します

どういう意味ですか?意図したことをどのように実装しますか。しなければならないのは嫌だ

while True:
    a = self.ser.read(1)
    if a == '/n':
        blqblq()
    elif a == '/r'
        b = self.ser.read(1)
        if b == '/n':
            nana()
4

1 に答える 1

4

シリアル データ ストリーム (EOF) の終了を検出する方法がないため、readlineにはタイムアウトを指定する必要があります。

readlineデータが送信されていない場合 (またはデータに改行が含まれていない場合) は無期限にブロックされますが、アプリケーションも同様です。のようなものを書くのはまったく問題ありません

def read(ser, queue):
    while True:
         queue.put(ser.readline())
threading.Thread(target=read, args=(ser, queue)).start()

またはより現代的な同等物

def read(ser, queue):
    for line in ser:
         queue.put(line)
threading.Thread(target=read, args=(ser, queue)).start()

ただし、読み取りスレッドは決して終了しないことに注意してください。したがってプログラムが例外的でない方法で終了する場合 (つまり、ユーザーが何らかの方法でプログラムを終了できる場合) は、読み取りスレッドに停止するように通知するメカニズムが必要です。このシグナルが確実に受信されるようにするには、タイムアウトを使用する必要があります。そうしないと、シリアル データがない場合にスレッドが無期限にブロックされる可能性があります。たとえば、これは次のようになります。

def read(ser, queue):
    buf = b''
    ser.timeout = 1  # 1 second. Modify according to latency requirements
    while not should_stop.is_set():
         buf += ser.readline()
         if buf.endswith('\n'):
             queue.put(line)
             buf = b''
         # else: Interrupted by timeout

should_stop = threading.Event()
threading.Thread(target=read, args=(ser, queue)).start()
# ... somewhat later
should_stop.set()  # Reading thread will exit within the next second
于 2013-09-11T11:40:30.793 に答える