2011-06-27 137 views
10

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

编辑:也许一些中间程序可以用来帮助这个,作为作家和读者之间的中介?

+2

你可以做类似'的mkfs的/ dev/RAM1 1048576'(或更大的数字,如果你想),并安装'的/ dev/ram1'任何地方即可。这可能与您可以获得的“非阻塞”接近。当然,默认情况下,它根本不是非阻塞的,只是速度非常快(但默认情况下,命名管道也不会)。非阻塞操作是程序需要在文件描述符上设置的操作。 – Damon

+0

我虽然关于这个选项,但在tmpfs或类似文件中创建文件,但是同时又一次写入和读取的问题依然存在。更像是自文件以来的写作和写作。一个程序写入文件结尾,另一个从头读取一些信息,现在需要删除第一行,所以写在最后和删除在同一时间,我找不到解决方案,我会用这个。 – morphles

+1

很难(如果不是不可能的话)在不编写程序的情况下做这样的事情。可能最重要的工作:重命名是原子的,所以每个生产者可以将每个单独的任务写入单独的临时文件,关闭文件并根据某种“众所周知的”模式对其进行重命名。每个消费者可以将下一个文件重命名为随机文件(以便其他消费者不会选择它),读取内容并删除文件。虽然这只能在每个任务级别上(无论生产者是否作为一个单元编写),而不是按行级别。 – Damon

回答

5

您可以使用特殊程序来达到此目的 - 缓冲区。缓冲区旨在尝试使写入端不断繁忙,以便在写入磁带驱动器时能够流式传输,但可用于其他目的。内部缓冲区是一对进程通过共享内存中的大型循环队列进行通信,因此您的进程将异步工作。如果队列已满并且写入程序进程(如果队列为空),则读者进程将被阻止。示例:

bzcat archive.bz2 | buffer -m 16000000 -b 100000 | processing_script | bzip2的> archive_processed.bz2

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

+0

谢谢您指出我不知道的程序,看起来很有趣,并且在某些情况下可能会有用。虽然它不完全是我想要的,我也无法做到我想要的,但我决定最有可能实施我自己的程序/守护程序来处理像我这样的案例。 – morphles

+0

另一个解决方案是使用队列守护进程,就像齿轮工人一样。您的“行”可能会在作为作业的memcache中持续存在。 –