Proper way to idle in Linux?

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Proper way to idle in Linux?

Postby '; DROP DATABASE;-- » Wed Mar 23, 2011 5:08 pm UTC

I'm writing a program which reads data from a socket and reacts to it. The main loop is basically:

Code: Select all

while(!shutdown) {
   for(i = 0; i < num_sockets; i++) {
      data = read_line(socket[i]); //returns null if no data available
      if(data) process_line(data);
   }
   idle(); //so as not to consume all CPU time
}
What I'm stuck on is how to actually implement the "idle" function. I can use sleep() with some small value (say 10ms), but I'm not sure that's the "proper" way to do it. I know on Windows, you use Sleep(0) to mean "give up the remaining timeslice and let some other process have the CPU now", but as far as I know sleep and friends on Linux only do timed delays.
So long as I have at least one socket, the idle doesn't appear to be necessary, as in my current implementation, I set a read timeout on each socket (they obviously can't be blocking when used in a loop like this) and if no data is available, read_line() idles for that amount of time; however this behaviour doesn't seem to be documented so I don't think I should rely on it. Besides that, if there aren't any sockets currently open, it becomes a tight loop eating CPU time.
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.

kmatzen
Posts: 214
Joined: Thu Nov 15, 2007 2:55 pm UTC
Location: Ithaca, NY

Re: Proper way to idle in Linux?

Postby kmatzen » Wed Mar 23, 2011 6:05 pm UTC

It might work better if instead of explicitly idling after polling each socket to just make a blocking call to select. Alternatively, you could use a higher level library like libevent to wrap the select call. libevent would be the more portable option.

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Re: Proper way to idle in Linux?

Postby '; DROP DATABASE;-- » Thu Mar 24, 2011 12:24 am UTC

Well, I can't make a blocking call unless it's able to return when any of several sockets with potentially non-contiguous FDs have data available. Changing the whole system to use a library just to idle seems overkill.
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Proper way to idle in Linux?

Postby You, sir, name? » Thu Mar 24, 2011 12:27 am UTC

'; DROP DATABASE;-- wrote:Well, I can't make a blocking call unless it's able to return when any of several sockets with potentially non-contiguous FDs have data available. Changing the whole system to use a library just to idle seems overkill.


Use O_ASYNC to get a signal when data is available, and pause() to wait for a signal.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

kmatzen
Posts: 214
Joined: Thu Nov 15, 2007 2:55 pm UTC
Location: Ithaca, NY

Re: Proper way to idle in Linux?

Postby kmatzen » Thu Mar 24, 2011 12:32 am UTC

'; DROP DATABASE;-- wrote:Well, I can't make a blocking call unless it's able to return when any of several sockets with potentially non-contiguous FDs have data available. Changing the whole system to use a library just to idle seems overkill.


That's the point of select. You give it a set of FDs and a timeout or set it to blocking. Then, once any of the FDs have data available or the timeout has expired, you just need to read a bit vector to determine which sockets to get data from.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Proper way to idle in Linux?

Postby Yakk » Thu Mar 24, 2011 2:29 pm UTC

Time to learn event-driven programming!

Avoid idling for any length of time. Your code becomes about messages, and not fundamentally about a stack.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
naschilling
Posts: 142
Joined: Wed Apr 06, 2011 2:52 pm UTC
Contact:

Re: Proper way to idle in Linux?

Postby naschilling » Wed Apr 06, 2011 6:07 pm UTC

'; DROP DATABASE;-- wrote:

Code: Select all

while(!shutdown) {
   for(i = 0; i < num_sockets; i++) {
      data = read_line(socket[i]); //returns null if no data available
      if(data) process_line(data);
   }
   idle(); //so as not to consume all CPU time
}


What you really want is this:

Code: Select all

fd_set fds;
int maxfd = -1;
struct timeval tv;

while (!shutdown) {
     /* If you move any of this initialization outside the while loop, the behavior
      * is undefined. TRUST ME! It must be done EVERY ITERATION.
      **/
     //The value of tv can be anything you feel like or NULL to wait indefinately
     tv.tv_sec = 0;
     tv.tv_usec = 1000;
     FD_ZERO(&fds);
     for (i=0; i<num_sockets; i++) {
          maxfd = MAX(maxfd, socket[i]);
          FD_SET(socket[i], &fds);
     }
     if (select(maxfd, &fds, NULL, NULL, &tv) > 0) {
          for (i=0; i<num_sockets; i++) {
               if (FD_ISSET(socket[i], &fds) {
                    dara = read_line(socket[i]);
               }
          }
     }
}
Fair Warning: This probably has typo's in it.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 10 guests