You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何隔离由socat和tee创建的与tty关联的PTY缓冲区?

解决串口TTY克隆后PTY互相阻塞的问题

问题根源

你当前的命令中,tee的两个输出分支是同步绑定的:当其中一个socat因为对应PTY未被读取、缓冲区满而阻塞时,tee无法继续向该分支写入数据,进而阻塞整个数据流,导致另一个PTY也无法接收新数据——本质是两个PTY共享了tee到socat的同一条同步管道,没有独立缓冲隔离。

解决方案

方案一:用UNIX域套接字实现完全独立的分流

这种方式通过中间套接字将串口数据分发到两个独立的socat进程,每个PTY拥有专属缓冲,互不影响:

  1. 启动串口到UNIX套接字的双向转发(支持多客户端,同时处理读写):
socat /dev/ttyACM0,rawer,nonblock,echo=0 UNIX-LISTEN:/tmp/serial_shared,mode=666,reuseaddr,fork,bidirectional

参数说明:

  • rawer:保持串口原始数据模式,避免格式转换干扰
  • nonblock:非阻塞读取串口,防止无数据时进程挂起
  • echo=0:关闭串口回显,避免写入数据被回读干扰
  • fork:每个PTY连接都会创建独立子进程,实现分流隔离
  • bidirectional:支持PTY向串口写入数据,满足你的写入需求
  1. 分别启动两个socat进程创建独立PTY:
# 创建第一个独立PTY
socat UNIX-CONNECT:/tmp/serial_shared PTY,rawer,link=/tmp/myPTY1,bufsize=2097152,nonblock
# 创建第二个独立PTY
socat UNIX-CONNECT:/tmp/serial_shared PTY,rawer,link=/tmp/myPTY2,bufsize=2097152,nonblock

参数说明:

  • bufsize=2097152:给每个PTY分配2MB独立缓冲,可根据数据量调整大小
  • nonblock:PTY端非阻塞写入,即使PTY未被读取,进程也不会阻塞,数据暂存到专属缓冲

方案二:用buffer命令为每个分支添加独立缓冲

直接修改原命令,为tee的每个分支添加独立缓冲进程,避免单一分支阻塞整个数据流:

socat /dev/ttyACM0,rawer,echo=0 SYSTEM:'tee >(buffer -s 2M | socat - "PTY,rawer,link=/tmp/myPTY1") | buffer -s 2M | socat - "PTY,rawer,link=/tmp/myPTY2"'
  • buffer -s 2M:为每个分支分配2MB独立缓冲,当PTY未被读取时,数据暂存在缓冲中,不会阻塞tee的输出,另一个分支可正常接收数据

验证方法

打开两个终端窗口,分别执行:

cat /tmp/myPTY1
cat /tmp/myPTY2

关闭其中一个窗口的cat进程,另一个窗口仍能持续接收串口数据;重新打开关闭的cat,会读取到缓冲中的所有数据。

内容的提问来源于stack exchange,提问作者Dan Pit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:15:29