【问题标题】:Nonblocking/asynchronous fifo/named pipe in shell/filesystem?shell/文件系统中的非阻塞/异步fifo/命名管道?
【发布时间】:2011-09-23 07:29:09
【问题描述】:

有没有办法在 shell 中创建非阻塞/异步命名管道或类似的东西?这样程序就可以在其中放置行,这些行将保留在 ram 中,并且当某些程序可以从管道中读取某些行时,将未读取的内容留在 fifo 中?程序也很可能同时对这个 fifo 进行写入和读取。起初我虽然也许这可以使用文件来完成,但是在网上搜索了一下之后,似乎没有什么好处可以来自文件同时读取和写入的事实。命名管道几乎可以工作,只是有两个问题:首先,如果另一端没有人,它们会阻塞读/写,其次,即使我让写入阻塞并设置两个进程写入管道,而没有人在读,通过尝试为每个进程写一行,然后尝试head -n 1 <fifo> 我只得到了我需要的一行,但是两个写进程都终止了,第二行丢失了。有什么建议?

编辑:也许可以使用一些中间程序来帮助解决这个问题,充当作者和读者之间的调解人?

【问题讨论】:

  • 你可以做类似mkfs /dev/ram1 1048576(或者更大的数字,如果你愿意)然后在任何地方挂载/dev/ram1。这可能与您所能获得的“非阻塞”一样接近。当然,默认情况下它根本不是非阻塞的,只是非常快(但默认情况下命名管道也不是)。非阻塞操作是程序需要在文件描述符上设置的东西。
  • 我虽然关于这个选项,在 tmpfs 或类似的文件中创建文件,但同时写入和读取的问题仍然存在。更像是写作和写作,因为它的文件。一个程序写入文件末尾,另一个程序从开始读取了一些信息,现在需要删除第一行,所以在最后写入并同时在前面删除,我找不到解决方案,我会使用这个。
  • 在不编写程序的情况下很难(如果不是不可能)做这样的事情。可能几乎起作用的东西:重命名是原子的,因此可以让每个生产者将每个单独的任务写入一个单独的临时文件,关闭文件并根据一些“众所周知的”模式重命名它。每个消费者都可以将下一个文件重命名为随机名称(因此另一个消费者不会选择它),读取内容并删除文件。虽然这只适用于每个任务级别(无论生产者作为一个单元编写什么),而不是每行级别。
  • 写一个连接两个管道(一个读一个写)并且自己做一些缓冲的小程序真的不可能吗?基本上类似于tee 的复制到私有映射。这可能会做你想要的。
  • 是的,我虽然关于使用其他程序来添加缓冲,但也许有一些程序已经可以用于此。

标签: linux shell pipe nonblocking fifo


【解决方案1】:

您可以为此目的使用特殊程序 - 缓冲区。缓冲区旨在尝试保持写入端持续忙碌,以便在写入磁带驱动器时可以流式传输,但您可以将其用于其他目的。内部缓冲区是一对通过共享内存中保存的大型循环队列进行通信的进程,因此您的进程将异步工作。如果队列已满而编写器进程将被阻止,您的读取器进程将被阻止 - 以防队列为空。示例:

bzcat 存档.bz2 |缓冲区-m 16000000 -b 100000 |处理脚本 | bzip2 > archive_processed.bz2

http://linux.die.net/man/1/buffer

【讨论】:

  • 感谢您指出我不知道的程序,看起来很有趣并且在某些情况下可能有用。虽然它不完全是我想要的,而且我无法用它做我想做的事,但我决定很可能我会为像我这样的情况实施我自己的程序/守护进程。
  • 另一种解决方案是使用队列守护程序,例如 gearman。您的“行”可以作为作业保留在内存缓存中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 2020-06-20
  • 2023-03-06
  • 2011-12-05
相关资源
最近更新 更多