Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Xino

macrumors member
Original poster
Sep 5, 2008
36
0
Maybe a simple question:
I've created an application and I need some help with executing a method every 5 minutes (or so).

My first idea about this was to create a while or for loop and increasing a variable. When the variable is high enough (lets say 10000) I execute the method and reset the timer. I think this will cause a high CPU load and besides that, there must be a nicer way to do this.

I've some experience with threads so I'm think of something with NSThread?
 

kpua

macrumors 6502
Jul 25, 2006
294
0
Agreed, but if you're writing a command-line app, you'll need to start the run loop for it to work. If its a GUI app, then don't worry, AppKit started it for you.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Does your program maintain state in memory that could not be persisted to a backing store? If not, i would say that having the program run the task once, then exit, would be best. Then you can use any number of scheduling tools like at or cron, or something OS X specific (i'm sure there's something) to run it every 5 minutes. Not that you should be sloppy, but this also keeps you from having to track down every memory leak, since your program does not need to run forever.

-Lee
 

HiRez

macrumors 603
Jan 6, 2004
6,250
2,576
Western US
Maybe a simple question:
I've created an application and I need some help with executing a method every 5 minutes (or so).

My first idea about this was to create a while or for loop and increasing a variable. When the variable is high enough (lets say 10000) I execute the method and reset the timer. I think this will cause a high CPU load and besides that, there must be a nicer way to do this.
One thing I can tell you is that that is NOT the way to go about it; you are correct that it would be very inefficient (also, doing increments on a variable willl run at different speeds on different machines and even on the same machine depending on load, so your timing would be very erratic). As others have mentioned, NSTimer or launchd are probably your best bets. If the interval is 5 minutes I think launchd would be better, but if there's a possibility you might want a shorter interval measured in seconds, then I'd probably say a continuously running background process with a timer would be best.
 

ChrisA

macrumors G5
Jan 5, 2006
12,581
1,695
Redondo Beach, California
Maybe a simple question:
I've created an application and I need some help with executing a method every 5 minutes (or so).

My first idea about this was to create a while or for loop and increasing a variable. When the variable is high enough (lets say 10000) I execute the method and reset the timer. I think this will cause a high CPU load and besides that, there must be a nicer way to do this.

I've some experience with threads so I'm think of something with NSThread?

First you could use "cron". This is the method that UNIX has used for the last 20+ years. But it works at the appliation level. It can run a program periodically. If you can possably use this method go for it, there is near zero overhead and you don't need to write any code to use it.

If you must manage this inside your program then the most universal way is to call sleep(). Read the sleep man page for more info.

A related system calls are alarm() and settimer(). The select() call can be used for this purpose too.

All of these are standard unix system calls that would work on linux or Solaris as well as Mac OS X. I try to write using things like this if i possibly can to keep the code portable.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
Maybe a simple question:
I've created an application and I need some help with executing a method every 5 minutes (or so).

My first idea about this was to create a while or for loop and increasing a variable. When the variable is high enough (lets say 10000) I execute the method and reset the timer. I think this will cause a high CPU load and besides that, there must be a nicer way to do this.

I've some experience with threads so I'm think of something with NSThread?

Code:
sleep (5);

will put your application (more precise: the thread executing the call) to sleep for exactly five seconds, with zero CPU usage.
 

Xino

macrumors member
Original poster
Sep 5, 2008
36
0
Cron or launchd are not helping with this problem because both (as far as I know) works at application level.

Code:
sleep (5);

will put your application (more precise: the thread executing the call) to sleep for exactly five seconds, with zero CPU usage.

Maybe this will work out indeed, I've to create a new thread and within that thread I must have a releasepool and within that releasepool a while(1) loop with a sleep(300) inside that? If this causes zero CPU load I think this will help me out :)

The other option "NSTimer" looks useful too as far as I kan see. Is a NSTimer the same as NSThread but with a timer? Does the following code runs the method handleTimer every 0.5 seconds?

Code:
timer = [NSTimer timerWithTimeInterval: 0.5
                 target: self
                 selector: @selector(handleTimer:)
                 userInfo: nil
repeats:YES];

It this causes a loop and executes handleTimer every 0.5 seconds, this is definitely the way I want.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Code:
sleep (5);

will put your application (more precise: the thread executing the call) to sleep for exactly five seconds, with zero CPU usage.

This isn't quite true, from the man page:
The suspension time may
be longer than requested due to the scheduling of other activity by the
system.

You have no guarantee that it will be exactly the number of seconds requested. Using usleep in tiny intervals until they add up might get you closer, but there are no guarantees there, either.

Otherwise, the high points have been covered, but:
a while(1) loop

this is bad times, in my opinion. Is it your expectation that your program will truly run for eternity? If not, and you have some condition inside the while that will cause you to break out of it, use that as your predicate, not 1. Even if you want to run "forever", it is still likely to be desirable that a signal can be caught and result in your loop gracefully terminating.

-Lee
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
The other option "NSTimer" looks useful too as far as I kan see. Is a NSTimer the same as NSThread but with a timer? Does the following code runs the method handleTimer every 0.5 seconds?

Code:
timer = [NSTimer timerWithTimeInterval: 0.5
                 target: self
                 selector: @selector(handleTimer:)
                 userInfo: nil
repeats:YES];

It this causes a loop and executes handleTimer every 0.5 seconds, this is definitely the way I want.

NSTimer is actually easier to use than a thread. If you have a Cocoa application with a run loop and event handling running, the NSTimer will basically insert a call to that selector into the run loop every 0.5 seconds. You have to worry about thread safety much less, because it is running in the main thread, along with all the other calls to your code that happen when the user moves a window, clicks the mouse, types a character on the keyboard etc.

I would only recommend using a separate thread if the action you take every five minutes takes a long time and would interfere with the responsiveness of your application; if it executes in a separate thread, your application will always stay responsive.
 

Xino

macrumors member
Original poster
Sep 5, 2008
36
0
Thanks all for your great help, I found out scheduledTimerWithTimeInterval was the most useful method for me...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.