/dev/null 是如何实现的?

Яро*_*лин 4 linux io io-redirection

我不明白当进程写入这个特殊文件时会发生什么。所有字节会发生什么?为什么写入 /dev/null 不占用 CPU 资源?如果你能根据 Linux 源代码的参考来回答,那就太棒了。

Arch论坛上有这样的答案:

缓冲区只是被忽略。

但是,当我执行例如 cat /dev/urandom > /dev/null 时,必须调用 write_null 函数多次,或者可能只调用一次,而且我不明白缓冲区是如何工作的。

Ste*_*itt 8

在Linux中,/dev/null是由许多函数实现的,包括write_null

\n
static ssize_t write_null(struct file *file, const char __user *buf,\n              size_t count, loff_t *ppos)\n{\n    return count;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

正如您所看到的,缓冲区完全被忽略,函数所做的只是返回要求写入的字节数。

\n

该函数可以被调用任意多次,并且每次调用都会产生少量的成本(调用内核的成本)。如果你跑

\n
cat /dev/zero > /dev/null\n
Run Code Online (Sandbox Code Playgroud)\n

该成本可能占主导地位。cat重复地从其输入(或给定的文件\xe2\x80\x99)读取并写入其输出,直到耗尽要读取的内容或无法写入。/dev/urandom然而,当阅读时,阅读内容更加复杂,我希望这些内容占主导地位。在这两种情况下,所有 \xe2\x80\x9cI/O\xe2\x80\x9d 都是 CPU 驱动的,并且cat最终将使用相当数量的 CPU(一个逻辑 CPU 的 100%)\xe2\x80\x94write_null尽可能快地调用内核,从而尽可能快地不执行任何操作。

\n

在更典型的情况下,/dev/null例如,当用于丢弃程序\xe2\x80\x99s 信息输出时,写入次数将少得多,并且与程序正在执行的其他操作相比,它们的总体成本可以忽略不计。

\n

(顺便说一句,您\xe2\x80\x99将在上面链接的代码中找到/dev/zero刚刚的实现。)/dev/null

\n