AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 694666
Accepted
user3544936
user3544936
Asked: 2022-03-17 10:20:32 +0800 CST2022-03-17 10:20:32 +0800 CST 2022-03-17 10:20:32 +0800 CST

限制终端输出缓冲区大小

  • 772

有没有办法限制终端应用程序缓冲的文本量,以输出到显示器?

例如,如果我要调用一个尽可能快地将 2,000,000 行写入标准输出的应用程序,该应用程序可能会很快返回,但终端可能会在返回空闲提示之前再花几分钟显示闪烁的文本墙。大概这 2,000,000 行文本已被缓冲,并且终端应用程序正在通过缓冲区工作,生成数千个显示更新。有没有办法限制缓冲区大小,如果有超过例如 1,000 行要渲染,最旧的就被丢弃?

terminal terminal-emulator
  • 1 1 个回答
  • 780 Views

1 个回答

  • Voted
  1. Best Answer
    egmont
    2022-03-19T07:28:55+08:002022-03-19T07:28:55+08:00

    如果我要调用一个尽可能快地将 2,000,000 行写入标准输出的应用程序,该应用程序可能会很快返回

    这不是它的工作原理。

    与管道类似,tty 行也具有相对较小的缓冲区大小。在我看来,终端行的内核缓冲区大小约为 12 kB。

    (我怎么知道?我不想研究任何现有的源代码,也不想编写测试工具。所以我启动了一个终端模拟器,查询它正在使用的 tty 行(tty命令,假设它说/dev/pts/5),然后冻结它通过发送 SIGSTOP。然后,从另一个终端,我使用非阻塞写入向其终端行发送了一些字节:dd if=/dev/zero of=/dev/pts/5 bs=65536 oflag=nonblock。)

    可能有多个缓冲区相互连接,例如,如果您正在运行tmux或类似情况,那么数据会通过两条 tty 线路以及 tmux 的内部缓冲,或者如果您ssh在 ssh 服务器、网络和 ssh 客户端上工作还要添加一些缓冲区,但是您将拥有的整体缓冲区大小仍然比您正在处理的数据量低很多(大约 100 MB,假设平均每行 50 个字节)。

    终端仿真器也以类似的小块读取它们的输入,例如大约 4 - 8 kB。

    (我怎么知道?我检查了/proc/<terminal's pid>/fd哪个文件描述符对应于终端行的主端/dev/ptmx,并 strace'd 终端仿真器从这个 fd 中寻找读取。)

    当应用程序将这么多数据发送到读取速度很慢的进程时,应用程序通常会阻塞它执行的写入操作。换句话说,读慢导致写也跑慢(更准确地说:有规律地进入“睡眠”状态,这样内核就可以运行其他进程,直到终端消耗了一些数据,进程可以写再次到 tty 线)。

    自己看:开始一个cat largefile需要一分钟左右的时间。在另一个终端定位cat的 PID(例如pidof cat),假设它是 12345。然后查看哪个 fd 连接到cat的输入文件:ls -l /proc/12345/fd,找到属于 的行largefile,很可能是 fd 编号 3。现在询问文件偏移量在哪个cat位置,读取其输入文件:cat /proc/12345/fdinfo/3. 您会注意到,当终端处理所有这些数据时,这个偏移量几乎呈线性增长;并且cat只会在视觉终端活动停止之前退出一点点(这种差异甚至可能无法通过手动执行的命令来测量)。


    再过几分钟

    在我相当普通的笔记本电脑上,带有一个性能相当不错的终端仿真器(不是最好的,但也不错),处理 100 MB 的数据大约需要 10 秒。

    数以千计的显示更新

    几乎每个图形终端仿真器都尽可能快地处理输入,而不会一直更新显示(这将非常慢),有时(理想情况下每秒 60 次,调整为显示的刷新率)会短暂停止处理输入为了更新显示。一些终端模拟器保持这个刷新率,如果有连续的输入流要处理,一些终端模拟器会自适应地跳过帧。我的显示器每秒刷新大约 25 次,即在处理 100 MB 流期间大约刷新 250 次。

    您要么拥有性能不佳的计算机或性能不佳的终端仿真器,要么夸大其词,或者您的数据更大。


    有没有办法限制缓冲区大小,如果有超过例如 1,000 行要渲染,最旧的就被丢弃?

    终端没有这样的功能。

    首先,他们需要一个更大的输入缓冲区,以确定他们是否可以进行这种跳过。大的输入缓冲区可能意味着在正常操作下不必要的显示更新延迟。

    其次,您的回滚缓冲区将被破坏,您将无法回滚以查看先前的输出。

    第三,即使是当前状态也可能被破坏,例如,如果它错过了改变颜色的转义序列或类似的东西。

    不,这将是一个完全错误的特征。终端仿真器必须处理它们收到的所有数据。


    那么,如果有一个正在运行的进程会打印出如此多的数据,以至于您必须等待几分钟,您该怎么办?

    您可以使用 (SIGINT) 中断该过程Ctrl+C,或者如果这不起作用,您可以尝试通常更具侵略性的Ctrl+\(SIGQUIT)。请记住,生产者应用程序几乎肯定仍在运行并且尚未打印这些数据——除非您将其中止。

    你可以切换到不同的终端模拟器选项卡或不同的应用程序,在那里做任何你想做的事情,然后再回到这个终端。

    你可以稍作休息,伸展一下,凝视远处的某个点几秒钟,这很好。

    您可以根据处理大量数据的速度来选择您喜欢的终端仿真器。

    如果您的工作流程经常涉及将这么多数据发送到您的终端,那么重新设计您的工作流程。例如,将给定应用程序的输出通过管道tail传输,显然,它可以比终端仿真器更快地处理数据(它与该数据的关系要少得多)。

    向终端发送 100 MB 数据(200 万行)不应该成为您常规工作流程的一部分。你作为一个人将无法浏览它,更不用说正确处理它了,那有什么意义呢?发送到终端的 2M 线不是数据,是垃圾。它应该只是偶然发生并且很少发生,因此必须等待它,或者必须终止应用程序并以显着降低的详细程度重新启动它,不应该成为问题。

    希望这可以帮助。

    • 0

相关问题

  • 寻找终端下载管理器

  • 语法错误:fd 编号错误?

  • traceroute,只打印网关信息

  • 如何在 ssh 上运行一瞥?

  • 备份 Nand Flash 存储区

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve