In Linux, /dev/null
is implemented by a number of functions, including write_null
:
static ssize_t write_null(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
}
As you can see, the buffer is completely ignored, and all the function does is return the number of bytes it was asked to write.
This function can be called any number of times, and there is a small cost associated with each call (the cost of calling into the kernel). If you run
cat /dev/zero > /dev/null
that cost is likely to dominate. cat
reads from its input (or the files it’s been given) and writes to its output, repeatedly, until either it runs out of things to read, or it fails to write. When reading from /dev/urandom
however, the reads are more complex, and I would expect those to dominate. In both cases, all the “I/O” is CPU-driven, and cat
will end up using a fair amount of CPU (100% of one logical CPU) — ultimately having the kernel call write_null
as fast as possible, which proceeds to do nothing as fast as possible.
In more typical circumstances, when /dev/null
is used to discard a program’s informational output for example, there will be far fewer writes and their overall cost will be negligible compared to whatever else the program is doing.
(Incidentally, you’ll find the implementation of /dev/zero
just after /dev/null
in the code linked above.)
null
device at https://www.leidinger.net/FreeBSD/dox/dev_null/html/da/dea/null_8c_source.html. Basically, all that has to happen when writing to/dev/null
is ... nothing. The device driver does nothing, and returns a successful result code.cat /dev/urandom
is pretty cpu intensive in itself so a do nothing process for every line added to it probably wouldn't add much.