mknod创建的命名管道与mkfifo创建的FIFO是否等效?


22

我已经使用该mkfifo <file>命令创建了命名的FIFO,其中一个进程写入文件,而另一个进程从文件读取。

现在,我知道该mknod命令能够创建命名管道。这些命名管道是否等效于由创建的FIFO mkfifo,或者它们具有不同的功能?

Answers:


29

是的,它是等效的,但显然只有在您告诉mknod您实际创建一个FIFO而不是块或字符设备时才这样做(这些天很少这样做,因为devtmpfs / udev会为您执行此操作)。

mkfifo foobar
# same difference
mknod foobar p

对于strace这两个命令,它是相同的:

mknod("foobar", S_IFIFO|0666)           = 0

因此,就系统调用而言,mkfifo实际上是的简写mknod

那么,最大的区别就是语义。有了mkfifo你可以一气呵成创建一批的FIFO:

mkfifo a b c

使用mknod,因为您必须指定类型,所以它只能接受一个参数:

# wrong:
$ mknod a b c p
mknod: invalid major device number ‘c’
# right:
mknod a p
mknod b p
mknod c p

通常,mknod很难正确使用。因此,如果要使用FIFO,请坚持使用mkfifo


16
尽管OP肯定不会在乎,因为Q没有被标记为[linux],请注意,在BSD上mkfifo(2) 确实是一个单独的系统调用mknod(2)(但是最终会做与完全相同的事情mknod(S_FIFO))。
mosvy

@frostschutz-谢谢您的出色回答。所以只是澄清一下。mkfifomknod实际使用中的程序mknod系统调用(不知道今天之前的系统调用)来创建一个FIFO。我猜您可以互换使用术语“ FIFO”和“命名”。它们是一样的吗?双向命名管道是通过Unix域套接字实现的,对吗?
Shuzheng

是的,“命名管道”和FIFO通常指的是同一件事(在管道的上下文中-FIFO是在管道外部也存在的概念)。套接字完全是另一种野兽,在这里对此
frostschutz

@frostschutz-谢谢。我想最让我困惑的是,当我想到命名管道时,我也想到了双向管道-FIFO绝对不是双向(AFAIK)。
蜀正

@Shhengheng FIFO确实没有任何关于方向的规则。它实际上只是读写。可以有任意数量的读取器和写入器,但是任何写入的内容只能读取一次,因此尚不清楚最终谁将获得数据。
弗罗斯特斯

18

除了在便携性的极端方面,它们是等效的。mknod ... p最初是创建命名管道的唯一方法,但是POSIX选择省略它,mkfifo而是发明了它,大概是因为命名管道本质上比其他任何东西mknod都可以使用设备及其主要和次要数字进行移植。该mknod系统调用也留下了POSIX的早期verions出来。

因此,对于可移植到古代UNIX而言,mknod ... p更好。对于现代系统,mkfifo它会稍好一些,尽管您不太可能会发现一个实际的现代Unix mknod ... p无法正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.