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

Shu*_*eng 23 fifo

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

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

fro*_*utz 29

是的,它是等价的,但显然只有当您告诉mknod实际创建 FIFO 时,而不是块或字符设备(这些天很少这样做,因为 devtmpfs/udev 为您做了)。

mkfifo foobar
# same difference
mknod foobar p
Run Code Online (Sandbox Code Playgroud)

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

mknod("foobar", S_IFIFO|0666)           = 0
Run Code Online (Sandbox Code Playgroud)

所以就系统调用而言,mkfifo实际上是mknod.

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

mkfifo a b c
Run Code Online (Sandbox Code Playgroud)

使用mknod,由于您必须指定类型,因此它只接受一个参数:

# wrong:
$ mknod a b c p
mknod: invalid major device number ‘c’
# right:
mknod a p
mknod b p
mknod c p
Run Code Online (Sandbox Code Playgroud)

一般来说,mknod很难正确使用。因此,如果您想使用 FIFO,请坚持使用mkfifo.

  • 虽然 OP 肯定不在乎,因为 Q 没有标记 [linux],请注意在 BSD 上,`mkfifo(2)` 确实是一个与 `mknod(2)` 分开的系统调用(但它最终会做与 `mknod(S_FIFO)` 完全相同)。 (16认同)

小智 18

除了在便携性的极端边缘之外,它们是等效的。mknod ... p最初是创建命名管道的唯一方法,但 POSIX 选择省略它并mkfifo改为发明它,大概是因为命名管道本质上是一个比其他东西mknod可以对设备及其主要和次要号码做的更便携的概念。该mknod系统调用也留下了POSIX的早期verions出来。

所以,对于古代 UNIX 的可移植性,mknod ... p是更好的。对于现代系统,mkfifo稍微好一点,尽管您不太可能找到实际的现代 unixmknod ... p不起作用。