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.)
nulldevice 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/nullis ... nothing. The device driver does nothing, and returns a successful result code.cat /dev/urandomis pretty cpu intensive in itself so a do nothing process for every line added to it probably wouldn't add much.