What is the correct way to multithread independent if
statements in a bash script? Is it best to place the &
after code contained in the if
or after the expression?
For an &
after the expression, it makes sense to continue threading as necessary if the if
contains a large block of code. But should one line of code also end with &
?
After the expression:
if [ expression ] &
then
#task
fi
After the task:
if [ expression ]
then
#task &
fi
Imagine 3 if
statements that all perform tasks independent of each other, how does the execution work with the different placement of the &
? From what I understand, if placed after the expression, all 3 expressions start (basically) simultaneously and so do the 3 tasks.
#Thread 1 #Thread 2 #Thread 3
if [ expr1 ] & if [ expr2 ] & if [ expr3 ] &
then then then
task1 task2 task3
fi fi fi
wait
If placed after the task code, the first if
would be evaluated and only as the first task begins would the 2nd if
be evaluated. The tasks are more staggered than simultaneous.
#Thread 1 #Thread 2 #Thread 3
if [ expr1 ]
then
task1 & if [ expr2 ]
fi then
task2 & if [ expr3 ]
fi then
task3 &
fi
wait
The expressions cannot be combined to do threading inside the if
such as:
if [ combined expression ]
then
#task1 &
#task2 &
#task3 &
fi
Bash else-if statement is used for multiple conditions. It is just like an addition to Bash if-else statement. In Bash elif, there can be several elif blocks with a boolean expression for each one of them. In the case of the first 'if statement', if a condition goes false, then the second 'if condition' is checked.
Technically speaking there is no multithreading in Linux shell script but it is possible to achieve the effect of multithreading inside Linux shell scripts. In other words, it is possible to achieve the ability to run Linux shell scripts in parallel background multiprocessing synchronization.
How to Use the Bash Sleep Command. Sleep is a very versatile command with a very simple syntax. It is as easy as typing sleep N . This will pause your script for N seconds, with N being either a positive integer or a floating point number.
If you want each if
condition to execute within the context of its respective "thread" (actually subshell process), then I think the thing to do is put the &
after the closing fi
statement for each if
. Then the evaluation of each if
expression, along with conditional code wiil occur entirely within the context of its own "thread".
For example:
#/bin/bash
if [ 1 ]
then
for i1 in {1..3}; do echo $i1; sleep 1; done
fi &
if [ 1 ]
then
for i2 in {a..c}; do echo $i2; sleep 1; done
fi &
wait
Output from each "thread" is interleaved as expected:
1
a
2
b
3
c
Note in all cases with &
, these are actually processes (created with fork()
) and not threads (created with pthread_create()
). See Multithreading in Bash. You can test this by creating a variable, e.g. n=0
before the "threads" are started. Then in one thread increment n and echo $n in all threads. You'll see each "thread" gets its own copy of n - n will have different values in the incrementing and non-incrementing threads. fork()
creates a new process copy (including independent copies of variables); pthread_create()
doesn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With