【问题标题】:Forwarding the in and output of a serial link to the stdin and stdout of an other process将串行链接的输入和输出转发到其他进程的标准输入和标准输出
【发布时间】:2015-10-13 12:21:51
【问题描述】:

我为嵌入式设备实现了一个串行协议,并调试了我在主机 [Widows 7 MinGW] 上编译的代码,只需使用标准输入和标准输出进行通信,现在我想使用虚拟零调制解调器电缆。

我认为编写一个 python3 脚本并不难,它完全可以获取程序的标准输出并将其转发到串行链接,同时将串行数据发送到标准输入,但是,我无法得到它跑步。这是我最好的尝试[我用 cat 替换了我的可执行文件]:

import subprocess
import serial
import threading

def forward_to_serial():
    while True:
        ser.write(proc.stdout.read())

def forward_to_cmd():
    while True:
        proc.stdin.write(ser.read())
        proc.stdin.flush()

ser = serial.Serial('COM27', timeout = 100)

proc = subprocess.Popen("cat", stdout=subprocess.PIPE, stdin=subprocess.PIPE)

fwc = threading.Thread(target = forward_to_cmd)
fwc.start()

forward_to_serial()

它不起作用可能是由于两个活动线程访问 Popen 对象。当我将问题减少到仅将数据从串行链接转发到 Popen 对象时,它会按预期工作

proc = subprocess.Popen("cat", stdin=subprocess.PIPE)

fwc = threading.Thread(target = forward_to_cmd)
fwc.start()

#forward_to_serial()

有没有办法让它工作?

【问题讨论】:

  • 如果ser.fileno()返回一个真实的文件描述符,然后尝试直接将它作为stdout参数传递,即,将中间人(Python)重定向子进程的标准输出直接剪切到串行。

标签: python subprocess python-multithreading pyserial


【解决方案1】:

read() method,当它的参数被省略时,会阻塞直到它从流中读取所有数据,直到子进程退出时才会发生。

您应该尽可能多地阅读操作系统在任何时候都会为您提供的内容,例如与read1() method。这样,如果您获得部分读取(因为子进程写入或用户键入了一些数据而没有关闭流),您可以立即转发它,而不是将其缓冲在内存中并等待流关闭。例如:

MAX_READ_SIZE = 4096
def forward_to_serial():
    while True:
        data = proc.stdout.read1(MAX_READ_SIZE)
        if not data:
            break  # EOF
        ser.write(data)

请注意,在forward_to_cmd() 的情况下,当从串行端口读取时,如果省略参数,serial.read() 确实具有相同的阻塞行为直到 EOF。相反,它默认为 1,因此每次调用只会尝试读取一个字节。

【讨论】:

  • 非常感谢,我不知道read1,但它只在使用read1(1)时有效
  • @the_architect:如果可以避免,您不应该使用 1 的缓冲区大小,这会导致性能下降。我建议使用更大的缓冲区大小,例如 4096,这样如果一堆数据立即可用,它会在单个系统调用中读取并在单个系统调用中写回;如果可用数据较少,仍会立即读取。
猜你喜欢
  • 1970-01-01
  • 2016-02-29
  • 2010-12-01
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 2012-03-16
  • 1970-01-01
相关资源
最近更新 更多