Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I am writing a daemon (my first) and it needs to wake up every second and check a special piece of hardware. I have it checking the hardware, but how do I make it sleep, then wake on a specific second?

I'd like to attach to the clock somehow and wake up using some kind of interrupt. Polling is out of the question as I don't want to spend the computer resources when idle.

  • Pascal
  • Ubuntu Server 10.10
  • No OOP
share|improve this question

3 Answers 3

OK, well, here's the solution I came up with. A bit of a pain, but...

First, when I am ready to wait for the next second, I get the current MilliSecond. This is the finest resolution I can get from the system.

Then, I subtract that from 1000 (1000 Ms per second) minus the current Ms equals the number of Ms I need to wait.

Then multiply that by 1 million (to convert to NanoSeconds)

Then use NanoSleep(blah,blah).

This seems to work.

PS, I compared the CPU usage (with top) between this method and one that simply polls waiting for the next second to arrive, and the polling version uses 98% CPU, and this uses 0.3%. This is the way.

share|improve this answer
    
I'm glad you came up with something. However, I'd like to point out that your solution is essentially a slightly more complex version of my solution, which you rejected. My approach simply cannot take 98% CPU while sleeping. It's impossible. If you found that in testing, then you didn't implement it correctly. It sounds like instead of sleeping, you were spinning in a loop constantly checking the time, which definitely would take that much CPU. And nobody suggested spinning in a loop polling the time. –  Scott Severance Jan 7 '12 at 14:22
    
I agree. In effect, I did use your approach, but simply sleeping for 1 second, had the efect of making my daemon drift a little bit. It would sleep for one second,but the overhead of the daemon made the total loop time more then one second. A tiny amount to be sure, but it was measurable. –  Mark Jan 7 '12 at 20:53

In one place, you say you want to poll on a particular second. In another place, you say that you want to poll every second. Which is it?

I think the easiest way would be to schedule it in the program loop[1] itself. I don't know Pascal, but surely it has some sort of sleep function.

Here's some pseudocode to give you the idea:

while(true) {
    check_hardware()
    sleep(1) //unit is seconds
}

If you want to only run on some specific second, just add a check for the second:

while(true) {
    if(get_time_as_seconds() in allowable_seconds()) {
        check_hardware()
    }
    sleep(1)
}

[1]: In your daemon, that is.

share|improve this answer
    
I do not want to poll. This is a server, and polling simply takes too much resources spinning in a loop waiting for a second to pass. Sleep sounds good assuming sleep returns control to the OS and allows other stuff to happen while sleeping. –  Mark Dec 23 '11 at 6:26
    
@Mark: You said you're writing a daemon. There's no concept of returning control to the OS or not doing so. Linux is a multitasking OS and has been since the beginning. It's not at all similar to DOS. And it's not true that polling would take too many resources. That's why the sleep() function is called. It means to do nothing for that amount of time, during which time the resources consumed would be negligible. –  Scott Severance Dec 23 '11 at 9:03
    
@Mark: Note also that the approach suggested by ams is the same basic approach as mine; the difference is that my approach is done in-process, while ams' uses one or more outside processes to handle the timing. If anything, mine is more efficient (since it doesn't rely on outside processes and signals), though in practice they'd likely be very similar. –  Scott Severance Dec 23 '11 at 9:06
    
Scott, Thanks for the advice. Sorry I wasn't clear about the timing of daemons needs, but I want it to wake up every second, then when finished return control to the OS using sleep vs polling. –  Mark Jan 7 '12 at 9:31
    
@Mark: My code does what you want. I think there's some confusion over terms, though. First, no daemon in existance takes over control from the OS, so no daemon can ever return control. It's impossible. Second, don't get hung up over the word "polling." Let's replace that word and say that my approach sleeps for one second and then checks the hardware. While sleeping, nothing is happening. No CPU is being consumed. Nothing until it's time to check the hardware again. –  Scott Severance Jan 7 '12 at 14:18

Look at alarm system call and SIGALRM handlers, as well as pause. I have no idea how to do that in Pascal, but presumably it'll be similar.

man 2 alarm
man 3 sleep

You might well find that sleep is more than enough for your needs. Indeed, the documentation says that this may even be implemented using alarm (although I believe it in not in Linux).

Note that all these things don't guarantee exactly when you wake. The times given are approximate. An alarm will not be delivered before the time given, but may be delivered a little late. Sleep has a similar issue, but may also return early if the process receives another signal.

share|improve this answer
    
This daemon looks at a hardware data acquisition board and logs data. The timing isn't that critical, but I do want to maintain order. I want to check the board every second (plus or minus.) I think, over a long time sleep will have large cumulative errors. Maybe alarm (or sigalrm) is the answer, The OS can lag a little, but overall, I will get 60 samples a minute. –  Mark Dec 23 '11 at 6:34
    
Don't forget, there's also nanosleep with which you can specify sub-second accuracy, and maybe iron out those issues, but perhaps alarm is the answer. BTW, alarm and SIGALRM are two halves of the same thing. –  ams Dec 23 '11 at 16:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.