1

I'm a bit confused about concurrency and parallelism in the bash shell. As I understand it, when we run commands in more than one subshells at the same time, these commands run in parallel on individual processor cores.

For example;

cmd1 & cmd2 & cmd3 & 

Here, the "ampersand" sign is run in the background (aka the subshells) of each command at the same time.It could be create in subshells in other ways. (Like writing in parentheses or using a pipe ..).

In this direction, the questions I wonder the answers of;

  • Bash provides parallelism through subshells, other hand is concurrency also achieved using another method on bash? As far as I know, concurrency works in a way that a single CPU executes operations intermittently. Do I need to implement a method externally to achieve this, or is bash already working this way (concurrency ) anyway.
  • If I occupy all CPU cores using parallelism, will the system crash or is there a protection mechanism against this situation?
  • What is the difference between the parallel I provide with subshells and the GNU Parallel tool? If the GNU Parallel tool works better, how does it achieve this?
  • Which of the "Parallel" or "Concurrency" operations works more efficiently?
  • What kind of losses are experienced when making "parallel" or "concurrency" operation, unlike normal (sequential execution of commands)?
3
  • Bullet point 2 contradicts point 1. You state correctly (but not fully) "concurrency works in a way that a single CPU executes operations intermittently". But then in point 2 ask what happens if we run out of cores. The answer to this, is that it is the same as if you have one core. Also have you tried running many processes at the same time? What happened? – ctrl-alt-delor Oct 22 '20 at 18:24
  • I answered some, the rest needs it's own question. – ctrl-alt-delor Oct 22 '20 at 18:37
  • @KamilMaciorowski foo & does mean “run foo in the background”. I don't know what you think “in the background” means, but that term is used in the manual of most shells, as well as in the POSIX specification, to describe the behavior of &. – Gilles 'SO- stop being evil' Oct 22 '20 at 20:42
2

How it works

You are correct in saying "concurrency works in a way that a single CPU executes operations intermittently": see http://ncce.io/wall-building

Concurrency can run on a single processor, therefore you don't need many cores, and it matters not if they are all in use.

If there are spare cores then the technique described above is not used, until there are more processes than cores.

There are overheads:

  • Creating the processes: much quicker than MS-Windows, but it still has overhead.
  • Communicating between processes.
  • Doing the concurrency: giving the illusion that many processes are running at the same time (It takes some effort to switch to running a different process).

What does bash do

Bash crease a new process, the Operating system kernel does the rest. When ever a process (any process) creates a new process, it is treated the same by the kernel. Here is an example of how to do it in python https://ctrlaltdelor.wordpress.com/2019/06/01/creation-of-an-interprocess-pipe-in-python-the-unix-gnu-linux-way/

2

As I understand it, when we run commands in more than one subshells at the same time, these commands run in parallel on individual processor cores.

No, this is not true at all. When you run multiple commands, they run concurrently on the system.

You can also say that the commands run in parallel. The expression “in parallel” has several meanings, but when talking about operating system design, it is usually synonymous to “concurrently”.

A process is not assigned a particular core. The system runs all processes concurrently. More precisely, the kernel runs all [threads](more precisely all threads) concurrently; a process can have more than one thread.

When a core is free, the kernel chooses a thread that has something to do (a ready thread) that isn't already executing on another core, and runs it on the free core for a while. Once the time slice is up, the kernel chooses another thread, and so on. Moving a thread from one core to another consumes some resources, but only a very small amount, so threads typically migrate from core to core very often.

Concurrency does not imply that all the threads run on the same core.

Here, the "ampersand" sign is run in the background (aka the subshells) of each command at the same time.It could be create in subshells in other ways. (Like writing in parentheses or using a pipe ..).

The commands run in the background, but if they're external commands, they aren't subshells. A subshell is a part of the script that runs in a separate process, or behaves as if it ran in a separate process (historically all subshells ran in a separate process but some modern shells can optimize this).

Both & and | run the left-hand side concurrently with the right-hand side.

Pretty much all of your other questions are moot because what you called “in parallel” does not happen at all.

1

What is the difference between the parallel I provide with subshells and the GNU Parallel tool? If the GNU Parallel tool works better, how does it achieve this?

"Better" is the keyword here. It is not faster (& takes in the order of 0.5 ms per job, GNU Parallel takes in the order of 5 ms/job), but it gives you a lot more control:

  • It can keep output from mixing: seq 100000 & seq 100000 & will mix output.
  • It can keep running a limited number of jobs in parallel.
  • It can run jobs remotely.
  • It can generate command lines from a template and multiple inputs.
  • It can retry failing jobs.

Just to name a few.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.