Elesmoth Elesmoth -4 years ago 93
Linux Question

How sleep mechanism works in Linux

We have an embedded Linux in which we manage and control many* subsystems. In addition, it has a communication medium which allows us to communicate with it without a cable(S-Band).
Currently, I am dealing with some scripts where we can use them during the operation period.

Here is a timer prototype, where we can activate some scripts when the clock shows 00:00.

while [ 1 ];
do
curHour="$(date +%H)"
curMin="$(date +%M)"
echo $curHour:$curMin
if ((10#$curHour=="0")); then
if((10#$curMin=="0"));then
./archAndComp.sh
fi
fi
sleep 60
done


The script I am calling has particular jobs which are archiving and compressing the desired directory. Here is the prototype of what I explained.

dirName="logs"
j=0
if (find $PWD $dirName*); then
i=0
while (find $PWD $dirName-$i.tar.xz);
do
let i++
done
tar -cvf $PWD/$dirName-$i.tar $PWD/var/log/$dirName
xz $PWD/$dirName-$i.tar
else
tar -cvf $PWD/$dirName-$j.tar $PWD/var/log/$dirName
xz $PWD/$dirName-$j.tar
fi


In summary, at the end of every day I want to archive and compress a specific directory. The file transfer/download script is provided. Thus, no need to discuss that part.

The thing that bugs me is; when the timer.sh script is active, does it cause a process sleep which does not allow any other process to be completed? Alternatively, some internal scheduler may assign the
sleep
to a thread-like mechanism which allows other processes to continue their lives...

For the first case, I should daemonize the timer script. What would be your suggestions, should I stick with systemd or implement my own clock-like daemon?

Answer Source

Eric Renouf has a point - unless you are really tight on memory on your embedded system, cron is a fine way to schedule running of other process on regular basis. However, if you decide to stuck with bash solution, there are some hints.

By custom while true is used for infinite loop. There are some technical details it could be a little better than while [1]. A little better as in: you may spare literally a few CPU cycles. So, it's not very bothering.

You choose quite elaborate way to choose if the hour to run a process arrived. It could be done simpler:

if [ "$(date +%H%M)" = "0000" ]; then
  ./do-something.sh
fi

There is no need to check the time every 60 seconds. You can check the current time and sleep until midnight:

while true; do
  t=( $(date +"%H %M %S") )   # store current hh:mm time into an array
  if [ "${t[0]}${t[1]}" = "0000" ]; then
    ./do_something.sh      # it could be a time consuming process
    t=( $(date +"%H %M") ) # so we want to know when it ends
  fi
  # sleep till next midnight
  sleep $[ 86400 - 3600 * ${t[0]} - 60 * ${t[1]} - ${t[2]} ] 
done

You may want to call your script in the background:

./my_scheduler.sh &

Also, you may want to keep the log from whatever you called from inside your scheduler:

./do_something.sh > /log/something.log 2>/dev/null

And as for your original question: the sleep from bash is implemented using the sleep(3) system call. More or less, it means for scheduler (a kernel subsystem deciding when to assign a CPU for a process/thread): do not run me, unless the specified time pass or some special happen. Therefore, sleeping process does not eat CPU resource.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download