【问题标题】:Equivalent to named pipes in Unix for LIFO/Stack structure等效于 Unix 中用于 LIFO/Stack 结构的命名管道
【发布时间】:2017-12-27 06:15:21
【问题描述】:

我一直在研究所有不同类型的 Unix 文件:常规文件、目录、设备文件、符号链接、门、套接字、命名管道……

但我找不到表现得像堆栈/LIFO 结构的文件类型。

众所周知,FIFO/命名管道相对于常规文件的优势如下:

来自https://askubuntu.com/questions/449132/why-use-a-named-pipe-instead-of-a-file

Linux 中几乎所有内容都可以视为文件,但常规文件和命名管道之间的主要区别在于,命名管道是文件系统上没有内容的文件的特殊实例.

来自man fifo

FIFO 特殊文件(命名管道)类似于管道,不同之处在于它是作为文件系统的一部分访问的。它可以被多个进程打开以进行读取或写入。当进程通过 FIFO 交换数据时,内核在内部传递所有数据而不将其写入文件系统。因此,FIFO 特殊文件在文件系统上没有内容;文件系统条目仅用作参考点,以便进程可以使用文件系统中的名称访问管道。

内核为每个由至少一个进程打开的 FIFO 特殊文件维护一个管道对象。 FIFO 必须在两端(读取和写入)都打开,才能传递数据。通常,打开FIFO会阻塞,直到另一端也打开。

所以我想知道这种类型的文件(LIFO/Stack)是否真的存在于 Unix 中?如果不是这样,有没有办法模拟一个?

我一直在考虑使用tac <named_pipe>,但我不确定这是否是一个好/可行的想法?

有没有更好的解决方案?

感谢您的帮助。

【问题讨论】:

  • 我一直想滥用 Bash 的 pushd -n item ; dirs +n ; popd -n 作为脚本中的堆栈。让我知道它是否有效。
  • 谢谢,但我不需要推送弹出目录,我想在内存中有一个空间,由 2 个进程共享,就像 stack/LIFO
  • 实现这一点并不难,但您首先要决定的是您要在堆栈中放入什么?字节?字符串? int 值?然后你必须决定如何存储这些项目,假设你实现了一个内核驱动程序。或者即使您存储了这些项目 - 也许您会阻止写入过程,直到它放入堆栈的项目被读取? (如果写入过程没有阻塞,您确实必须存储项目 - 但是您必须控制可以存储的数量......)需要做出很多设计决策,并且它们会做出非常具体的决定堆栈。

标签: linux file unix data-structures ipc


【解决方案1】:

Linux 中几乎所有内容都可以视为文件,但常规文件和命名管道的主要区别在于,命名管道是文件系统中没有内容的文件的特殊实例。

查看它的更好方法是说命名管道是出现在文件系统中的管道。它没有存储在磁盘上的内容,但它也不仅仅是一个空的 inode —— 它具有特定于管道的特定行为。

所以我想知道这种类型的文件(LIFO/Stack)是否真的存在于 Unix 中?

不,它不存在。与队列不同,堆栈不能被视为流;而且,无论如何,它在多进程环境中并不是一个特别有用的结构。让多个进程同时从堆栈中推送/弹出数据是没有意义的。

我一直在考虑使用tac <named_pipe>,但我不确定这是否是一个好/可行的想法?

那是行不通的。 tac 将读取管道的全部内容,之后管道中将没有任何内容。

【讨论】:

  • 感谢您的回答,确实,后进先出不是常规的输入/输出/错误stream,我同意tac 在阅读时会清空整个堆栈...任何更好的方法模拟一个?
  • “这没有意义......”任务创建子任务的任务调度程序是一个有用的例子。在这种情况下,与类似 BFS 的执行(来自 FIFO)相比,类似 DFS 的执行(来自 LIFO)利用更多的时间局部性。
【解决方案2】:

堆栈是一种非常有用且合理的结构。它非常适合 LIFO 任务处理程序,例如程序的堆栈。 虽然通常不是多进程,但我只需要通过 pthreads 进行多线程这样的使用(线程之间的共享内存有助于缓解 IPC),并通过控制线程创建和终止来避免使用显式堆栈。如果您需要线程从共享堆栈中弹出,您可以这样做,只要您使用互斥锁正确阻止该线程和任何相关部分。 (您需要确定推送和弹出是否同时发生,您的弹出是否应该等待推送完成以便您可以弹出刚刚推送的内容,或者等待弹出完成以便您的推送发生在低一层,或者它只是先到先得)。

如果您坚持多进程而不是单进程和多线程,您可以使用 IPC 管道和管理堆栈的附加进程来构建自己的实现。堆栈管理器将通过命名管道接受推送和弹出请求,并将弹出的数据推送到另一个命名管道。您必须对数据进行结构化,以便将其与推送/弹出命令区分开来,或者将推送的数据放在第三个命名管道上。您必须了解管道缓冲区和使用情况,以免交叉或拆分流。

【讨论】:

    猜你喜欢
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2011-12-26
    • 2015-04-07
    • 1970-01-01
    • 2021-08-20
    • 2011-03-25
    相关资源
    最近更新 更多