Question to ponder
cat | cat | cat | cat
Are the 4 unix
cat(concatenate) utilities running concurrently ?
Are they also running in parallel ? If they are why ? If they are not, why ?
So are the 4 cat commands. Yes the commands are concurrently started and active in the process list as shown in the example below
Code:
$ echo $$
630818
$ cat | cat | cat | cat
630818 pts/0 Ss 0:00 \_ -bash
630844 pts/0 S+ 0:00 | \_ cat
630845 pts/0 S+ 0:00 | \_ cat
630846 pts/0 S+ 0:00 | \_ cat
630847 pts/0 S+ 0:00 | \_ cat
But are they all running parallel now ? Nope, they are all blocking on the STDIN.
However if I do this, are they all running in parallel ?
Code:
$ </dev/zero cat | cat | cat | cat >/dev/null
Yes. Like an assembly factory where all the workers lining up in a pipeline are working concurrently and in parallel.
Below in a snapshot of the
top utility
Code:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
630818 ubuntu 20 0 8740 4736 3072 S 0.0 0.3 0:00.03 `- bash
630902 ubuntu 20 0 5740 1408 1280 S 36.0 0.1 1:19.44 `- cat
630903 ubuntu 20 0 5740 1408 1408 S 64.0 0.1 1:56.95 `- cat
630904 ubuntu 20 0 5740 1536 1408 R 70.0 0.1 1:55.09 `- cat
630905 ubuntu 20 0 5740 1408 1408 S 30.0 0.1 1:07.50 `- cat
Working in parallel doesn't mean doing the same things exactly at the same time.
The leftmost
cat may be working on item X, while the rightmost
cat will be working on item X-4, depending on how fast the data are pass across the pipeline.
However one could also have the
cat commands replaced as subprocess which depends on nothing on the
stdin and
stdout streams, hence
Code:
$ (while true; do echo 1 >/dev/null; done) | (while true; do echo 1 >/dev/null; done) | (while true; do echo 1 >/dev/null; done) | (while true; do echo 1 >/dev/null; done)
Each subprocess could be rewritten as a shell script and invoke like this
Code:
$ script.sh | script.sh | script.sh | script.sh
Hence you wouldn't know what is going on in the
script.sh until you read the codes.
Here you will find the subprocesses are running concurrently and in parallel with nothing worthy being done and yet occupying very significant cpu load
Code:
630818 ubuntu 20 0 8740 4736 3072 S 0.0 0.3 0:00.04 `- bash
630957 ubuntu 20 0 8740 3168 1408 R 49.5 0.2 0:57.85 `- bash
630958 ubuntu 20 0 8740 3168 1408 R 48.5 0.2 0:57.85 `- bash
630959 ubuntu 20 0 8740 3168 1408 R 48.5 0.2 0:57.84 `- bash
630960 ubuntu 20 0 8740 3168 1408 R 47.5 0.2 0:57.84 `- bash
If you understand how unix processes works, you can often take advantage of certain constructs that has unorthodox way of using them.
Simply Interprocess Communication (IPC) in Unix is an extremely powerful pillar construct which grows into other like named pipes, fifo, file streams and descriptors, semaphores, shared memory, message queues and more which is offered in Unix kernels all at your disposal.
I originally try to set a question to explain on these, but I realise that question is too narrow in scope and doesn't explain correctly.
Hence I removed it and put out this explanation for interested parties to discuss.
