cat
阻止了我在其中看到的内容代码,即它使用阻塞read()
,然后使用阻塞write()
。
我想调用一些工具,在其中按目的禁用所有标准输出缓冲(例如,如所描述的这里),因为该工具可能会调用子进程,并且我希望 stdout 上所有子进程的所有写入都将在同时写入时同时发生。
然后,我想将该标准输出通过管道传输到cat
(或类似的)多线程版本中。目的是真正的标准输出会很慢(它是磁盘上的文件),但我不希望该工具在尝试在标准输出上写入时挂起。如果我愿意的话
stdbuf -oL mytool
那么当磁盘繁忙时它就会挂起。当我做
stdbuf -oL mytool | cat
我实际上并不完全确定会发生什么。我可能会得到一些额外的缓冲内核管道缓冲区,尽管我认为当我禁用 的 stdout 缓冲时不会使用它mytool
。然后默认情况下,stdoutcat
也会被缓冲,但是当cat
真正写出它的stdout时,它可能会挂起。mytool
当它写东西但cat
不同时读取时会挂起。
这就是为什么我正在寻找一个cat
在写入时同时读取的多线程,因此写入标准输入multi-threaded-cat
永远不会被阻塞(或者只是软阻塞或任何你所说的)。它基本上在multi-threaded-cat
.当multi-threaded-cat
尝试写入 stdout 时挂起时,这并不重要,因为它仍然会并行地从 stdin 读取。所以我想做:
stdbuf -oL mytool | multi-threaded-cat
我希望multi-threaded-cat
总是尽快消耗传入的数据。这就是为什么我认为它可能应该是多线程的。否则,如果它使用 write(),则可能会阻塞或至少会出现一个小问题,同时,它无法从 stdin 读取()。
我也希望multi-threaded-cat
尽快写出数据。所以它不应该先填充自己的缓冲区然后写入,我希望它总是立即写入。
我的用例是这样的:mytool,包括一些子进程,将在标准输出上写入一些日志信息。stdbuf
很重要,这样我就不会在输出中出现任何延迟,而且所有子进程的标准输出都会同步。所有的标准输出将被重定向到文件服务器上的日志文件,这有点慢,并且在等待所有写入完成时会大大降低性能。这就是为什么我想要multi-threaded-cat
介于两者之间的东西。
有这样的工具吗?
我刚刚实现了我自己的这样的工具这里。与不使用它相比,使用它已经使我的速度提高了 800%。但也许还有其他工具或其他方法可以做我想做的事?
答案1
“多线程”是一个实现细节,而不是您实际需要的:多线程cat
实现仍然可能会阻塞,一个线程等待另一个线程,因为它正在等待某个地方来放置它所读取的数据。您正在寻找的是非阻塞 cat
,具有可能无限的缓冲区。
该sponge
实用程序来自Joey Hess 的 moreutils这是一个极端的版本:它首先将整个文件读入内存,然后写入输出。这可能适合你,也可能不适合你。
pv
让您指定缓冲区大小。您不能拥有无限的缓冲区,但您可以设置一个非常大的最大大小(如果您愿意,可以将其设置为与您的内存一样大),缓冲区仅根据需要分配。
stdbuf -oL mytool | pv -q -B 1g >output-file