PDA

View Full Version : Most efficient way to run a process every 5 minutes



Lilith
18th April 2008, 12:46 AM
I've got a project going and it's heavily reliant on processes running at regular intervals.

What is the correct and most efficient way to do this under OSX 10.4.11 or maybe later if I upgrade to 10.5.3/4?

I think I'm supposed to have a glazed look in my eye and run through a field of buttercups, casting petals left and right as I exclaim "launchd is the way, cron is uncool".

But I was looking at the man page for 'sleep' the other day. It also includes an example. I figure that at the shell level it has to not hog the cpu or memory> But I can't be sure either. I think the 'top' command is behind the Terminal utility and in its default state it takes 10% of the cpu when I'm doing nothing else. So shell commands are not necessarily ideal.

I have a variety of scripts to run so I just need something that can get this suite of scripts going at certain intervals. The 'delay' in shell script to my thinking has to be a lousy way to implement what I want.

Would I be better in the long run bothering to get my head around the Apple imposed launchd way?

decryption
18th April 2008, 12:47 AM
launchd is king - may as well learn it and have a useful skill :)

MacDave
18th April 2008, 06:21 AM
launchd is cool, but you could also do it the old-fashioned UNIX way with cron to schedule commands to run at various times. Though cron is deprecated in Tiger and Leopard, it still works fine.

In terminal, to see relevant man pages:

man cron

man crontab

man 5 crontab

man at

By the way, to run a command every five minutes, one would edit /etc/crontab (to do the job globally) and put a line like this:

*/5 * * * * Username /path/to/command

Username can be any valid user on the machine including "root."

Also, you may be interested in Lingon for creation of launchd configuration files:

Lingon 2.0.2 - MacUpdate (http://www.macupdate.com/info.php/id/19879/lingon)

Dave

Comet
18th April 2008, 07:22 AM
Well the crontab is really the way to go if you want to execute something at a set interval. Sleep won't remove the process. I haven't looked at launchd, but I think it'll be a benefit to learn what crontabs are, and how to use them efficiently.

SyncMan
18th April 2008, 07:53 AM
I have an Shareware App and Applescript that very works well, no UNIX needed, do you want the details?

chrism238
18th April 2008, 08:21 AM
You haven't really described how precisely your timing needs to be.

Within a shellscript, running the shell's builtin sleep command will give you the ability to sleep for a value that must be a multiple of a second, and your tasks will pause for at least that time, often a second or two more depending on how busy your system is.

If greater accuracy is required you should sleep from *inside* an already running process, using the library function sleep() for a second's granularity, or using the system calls nanosleep() or usleep() for much finer resolutions. While any of these calls is running, the process will consume *no* CPU time, unless you have other threads still running within the process.

Keep in mind that with launchd and cron, as suggested by others, that cron only checks for potential new activities once per minute, so you lose a lot of restart resolution.

purana
18th April 2008, 08:31 AM
Lingon 2.0.2 - MacUpdate (http://www.macupdate.com/info.php/id/19879/lingon)


:thumbup: Great util, found this a few weeks back.

Lilith
18th April 2008, 01:15 PM
Thanks for the replies. Still trying to get my head around all this.

I can sense now why I'm supposed to be excited about launchd taking over all timing/scheduling parts of the software running our Macs. Having just one "boss" process in charge of all this is intuitively sensible. Plus having a very uniform mechanism to control all these processes while the Mac is trying at power-on to pull itself up to the login window and then displaying the desktop I think will have long term benefits, especially for security.

I had seen Lingon. But I went back to the website and just now noticed that it has support for 10.4. Thanks.

There's also Launchd Editor | codepoetry (http://www.codepoetry.net/products/launchdeditor) plus I think my XCode stuff has a property editor too - not that I've ever powered that up.

The property lists remind me of xml.

soulman
18th April 2008, 02:38 PM
Just as another option - this is pretty straightforward to do in AppleScript. The following code will (tested under 10.5.2) do what you want as long as you save it according to the instructions below:


property appToRun : "" -- holds the location of the app once we have run for the first time

on run
if appToRun = "" then set appToRun to (choose application as alias) -- this stores the app location info if nec.
end run


on idle
tell application "Finder" to open appToRun -- just like double-clicking on an app
return 300 -- seconds until the next time we open the app
end idle
Paste this into a Script Editor document and save it as an Application & make sure you check the "Stay Open" checkbox.

Edit: Just re-read your post and not sure if this is in fact what you need - I see you need to run scripts rather than apps & figure these are shell scripts. You could still do it with AS easily enough but it would be slightly different to this.

Lilith
19th April 2008, 12:40 AM
Yes Soulman, thanks. Also:

Applescript Forums | MacScripter / Idle Thoughts (http://bbs.macscripter.net/viewtopic.php?id=24568)

is useful for anyone wanting to learn about "on idle". It does seem that "on idle" is efficient with system resources after further digging today and this surprises me. I think it was improved in Tiger or maybe 10.3.

I also have figured out that launchd does indeed support running something every five minutes, exactly as per Macdave's post - with cron syntax, but input into the StartCalendarInterval property key in my plist.

-------------------

Here's what I need to do: run this process "A" every five minutes iff a certain application "B" is running. Process "A" is an Apple Script and really must be an Apple Script (it hacks into application "B" but that's a separate issue).

The simplest solution I can think of is:

Apple Script "A" launches application "B" from it's "On run" block. "On idle" does what it has to do every five minutes if application "B" is still running. If App "B" is NOT running then quit.

So every time I want to run App "B" I just run script "A" instead. I couldn't figure out a way to just double click on the app "B" icon and get some daemon to see that since app "B" is running then go and run AS "A". Still don't know how to do that.

This avoids learning about launchd (gee I'm gutless) but I'll be watching the cpu usage like a hawk.

thorevenge
19th April 2008, 12:53 AM
The property lists remind me of xml.

It is XML. I think its to provide a standards based method of performing configuration much like Tomcat is all XML config based.

Lilith
21st April 2008, 01:10 AM
Well, I thought I'd post for the record...

I wrote entirely in Apple Script with a few shell commands here and there. Timing is not critical.

I've had a "return xxx" statement in my "on Idle" handler in my Apple Script and it really does seem to be efficient with cpu usage. The "xxx" is the number of seconds the Apple Script will be idle before the "on idle" is invoked again. So a value of 300 gives my 5 minutes.

No cpu is chewed during this idle period. Plus, I have several "delay" statements in the AS and although the AS does indeed wait, the sum total of all these waits is way way less than cpu used. In other words, the AS appears to be sent to the background and is being managed by something else and I reenter the AS when the delay period is up.

This has given me a new respect for interpreted (script) languages.

Sure it's nothing like machine code or even C++ in terms of speed but I can't do C++ so AS will do me for now.

Mikey D
24th April 2008, 11:15 AM
good stuff :)

Generally agree that Cron would be the way to go though.