Reputation: 33
process p3 completes first than the other two but the process is waiting till the process p1 is completed and the end_time is the same for all the 3 processes. But i want to get the timestamp of p3 process as soon as it is completed and the same with p2 and p1. Thanks in advance
p1_start_time=`date "+%Y-%m-%d %H:%M:%S"`
sleep 100 &
p1=$!
p2_start_time=`date "+%Y-%m-%d %H:%M:%S"`
sleep 60 &
p2=$!
p3_start_time=`date "+%Y-%m-%d %H:%M:%S"`
sleep 20 &
p3=$!
$(wait $p1 ; rc=$? ; p1_end_time=`date "+%Y-%m-%d %H:%M:%S"`) &
$(wait $p2 ; rc=$? ; p2_end_time=`date "+%Y-%m-%d %H:%M:%S"`) &
$(wait $p3 ; rc=$? ; p3_end_time=`date "+%Y-%m-%d %H:%M:%S"`) &
wait
echo "out of wait"
echo "$p1_end_time"
echo "$p2_end_time"
echo "$p3_end_time"
Upvotes: 1
Views: 152
Reputation: 35116
The 3x backgrounded (aka 'child') pids (p1 / p2 / p3) are available to the main/calling process (aka the 'parent'). Only the 'parent' process can use the wait
command to wait for the 'child' processes to complete.
For each of the $(wait $p ...)
constructs a separate OS-level process is spawned and while you can pass the background pids to these new processes, said processes are not the 'parent' of said background pids; the net effect is the three wait $p#
calls are (effectively) ignored and the 3x p#_end_time
variables are immediately populated with the current date/time. But, keep in mind the 3x p#_end_time
variables are being assigned within separate sub-processes which means when said processes exit the associated p#_end_time
variables are discarded (ie, the values are not passed back 'up' to the main/calling process).
Also keep in mind that when a process is put in the background it is executed asynchronously, which means a separate OS-level process is spawned. In order to pass data back 'up' to the main/calling process (eg, in this case the end time of the background processes) it becomes necessary to implement some sort of inter-process communications or use an intermediate storage option for sharing data (eg, pipe, file, database table, queuing system, etc).
One idea for capturing the separate end times:
sleep
, write the current date/time to a temp file; this is how we'll pass data 'up' from the background (aka child) processes to the parent processOne implementation:
unset pstart pend # delete any variables with these names
pstart=() # init arrays for
pend=() # start and end times
outdir=$(mktemp -d) # create temp directory for storing temp files containing end date/times
stime=100 # initial sleep time
for i in {1..3} # we'll do 3x passes through the loop
do
pstart["${i}"]=$(date "+%Y-%m-%d %H:%M:%S") # save the start date/time
# kick off sleep + 'echo date/time > temp file' in the background; each sub-process will have a different OS-level pid == BASHPID
(sleep "${stime}"; echo "${i} "$(date "+%Y-%m-%d %H:%M:%S") > "${outdir}/${BASHPID}") &
stime=$((stime-40)) # OP's example just happens to use times that are 40 seconds apart
done
wait # wait for all background processes to complete
# load our end times into the pend array
while read -r i dt
do
pend["${i}"]="${dt}"
done < <(cat "${outdir}"/[0-9]*)
# display start/end times for our processes (OP can reformat as needed)
for i in {1..3}
do
echo "process #${i} start/end times: ${pstart[${i}]} - ${pend[${i}]}"
done
# get rid of the temp directory and files
'rm' -rf "${outdir}" >/dev/null 2>&1
The output from a sample run:
process #1 start/end times: 2020-10-14 22:49:28 - 2020-10-14 22:51:08
process #2 start/end times: 2020-10-14 22:49:28 - 2020-10-14 22:50:28
process #3 start/end times: 2020-10-14 22:49:28 - 2020-10-14 22:49:48
Upvotes: 2