I have added to my explanation a bit. Conceptually, I am running a script that processes in a loop, calling shells that use the line content as an input parameter.(FYI: a kicks off an execution and b monitors that execution)
- I am needing 1a and 1b to run first, in paralell for the first two $param
- Next, 2a and 2b need to run in serial for $params when step 1 is complete
- 3a and 3b will kick off once 2a and 2b are complete (irrelevant if serial or parallel)
- Loop continues with next 2 lines from input .txt
I cant get it to process the second in serial, only all in parallel: What I need is the following
cat filename | while readline
export param=$line
do
./script1a.sh "param" > process.lg && ./script2b.sh > monitor.log &&
##wait for processes to finish, running 2 in parallel in script1.sh
./script2a.sh "param" > process2.log && ./script2b.sh > minitor2.log &&
##run each of the 2 in serial for script2.sh
./script3a.sh && ./script3b.sh
I tried adding in wait, and tried an if statement containing script2a.sh and script2b.sh that would run in serial, but to no avail.
if ((++i % 2 ==0)) then wait fi
done
#only run two lines at a time, then cycle back through loop
How on earth can I get the script2.sh to run in serial as a result of script1 in parallel??
@tripleee I put together the following if interested (note:I changed some variables for the post so sorry if there are inconsistencies anywhere...also the exports have their reasons. I think there is a better way than exporting, but for now it works)
Locking!
If you want to parallelize
script1
andscript3
, but need all invocations ofscript2
to be serialized, continue to use:...but modify
script2
to grab a lock before it does anything else:Note that you must not delete the
.lock2
file used here, at risk of allowing multiple processes to think they hold the lock concurrently.I understand your question like:
You have a list of models. These models needs to be run. After they are run they have to be transferred. The simple solutions is:
But to make this go faster, we want to parallelize parts. Unfortunately
transfer_result
cannot be parallelized.model1
andmodel2
are read from a text file.run_model
can be run in parallel, and you would like 2 of those running in parallel.transfer_result
can only be run one at a time, and you can only transfer a result when it has been computed.This can be done like this:
run_model {} && sem --id transfer transfer_model {}
will run one model and if it succeeds transfer it. Transferring will only start if no other transfer is running.parallel -j2
will run two of the these jobs in parallel.If transfer takes shorter than computing a model, then you should get no surprises: the transfers will at most be swapped with the next transfer. If transfer takes longer than running a model, you might see that the models are transferred completely out of order (e.g. you might see transfer of job 10 before transfer of job 2). But they will all be transferred eventually.
You can see the execution sequence exemplified with this:
This solution is better than the
wait
based solution because you can run model3 while model1+2 is being transferred.You are not showing us how the lines you read from the file are being consumed.
If I understand your question correctly, you want to run
script1
on two lines offilename
, each in parallel, and then serially runscript2
when both are done?The
while
loop contains tworead
statements, so each iteration reads two lines fromfilename
and feeds each to a separate instance ofscript1
. Then wewait
until they both are done before we runscript2
. I background it so thatscript3
can start while it runs, and background the wholewhile
loop; but you probably don't actually need to background the entire job by default (development will be much easier if you write it as a regular foreground job, then when it works, background the whole thing when you start it if you need to).I can think of a number of variations on this depending on how you actually want your data to flow; here is an update in response to your recently updated question.
If this still doesn't help, maybe you should post a third question where you really actually explain what you want...
I am not 100% sure what you mean with your question, but now I think you mean something like this in your inner loop: