3

I have a questions regarding alternate ways to delay a program in C++ besides sleeping.

I have a part of my program that receives and sends UDP packets to a controller. This part of the program has to run asynchronously. In order to reduce the overhead of this provider I decided to use asynchronous IO to receive the UDP packets rather than having a separate thread monitor the socket.

I followed this example of a sigaction to accomplish this. I noticed that if I try to use usleep while this sigaction is active it will break my sleep whenever I receive a packet. This kind of makes sense since I assume the sigaction is triggered by some sort of interrupt on the CPU which might stop the CPU from sleeping. If anyone has a good explanation for why this happens I would be curious to know. My issues is that there are times where I have to send several packets in succession and need to make sure to delay them otherwise they are missed by my controller.

I usually would use a sleep to delay the sending of the packets, but now I can't because of it gets broken by my sigaction. I have thought about maybe using a busy wait, but it might be too inconsistent. I have also though about maybe using a queue of packets that is emptied at regular intervals using a timer, but it seems like there might be a simpler solution.

Is there another way to delay the sending of the packets besides sleeping? Is there a way to set up my asynchronous IO so it does not break the sleep? Am I going about this in the wrong way?

  • 6
    If you find a need to sleep until the async operation is completed then you just don't have any use at all for async. Might as well do it synchronously. – Hans Passant Oct 02 '14 at 18:40
  • I should clarify only the receiving is done asynchronously. The sending is done whenever I make a call to send a packet in the main process. The problem is that the asynchronously operation breaks all sleeps in the thread it was initialized from. – Zeke Gunnink Oct 02 '14 at 19:38

2 Answers2

4

Usually when writing an asynchronous program you switch over to an event loop style of programming. Any event system will give you the ability to setup timers which trigger callbacks, using those you can setup schedules for sending traffic and that sort of thing. In addition you typically use them to watch your sockets and simply invoke your callbacks when there is something to be read. While not important for UDP, if you're dealing with TCP at any point you also want to use them to invoke callbacks when sockets are ready to be written to, that way you don't ever block your process while trying to write out data.

I personally like http://libevent.org/ though I've heard good things of libev as well.

hexist
  • 5,151
  • 26
  • 33
  • Thank you for your input. I think you're right I should probably move to a more event driven structure. I really shouldn't be using sleeps for flow control anyway. Thank you for the link, I will check out libevent. – Zeke Gunnink Oct 02 '14 at 19:43
2

This should clarify some things:

from sleep manual:

Return Value
Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler. 

One option would be to create loop which checks if time already elapsed (since sleep return number of seconds left when interrupted) or not. if not just execute another sleep and so on, to the end of required time.

RaFD
  • 688
  • 6
  • 14
  • That is a pretty good idea I forgot it returned a value. Edit: Actually I use usleep because I need millisecond precision and it only returns -1 or 0, (http://linux.die.net/man/3/usleep) but thanks for the suggestion! – Zeke Gunnink Oct 02 '14 at 20:02
  • So then you can try nanosleep (from manual): If the call is interrupted by a signal handler, nanosleep() returns -1, sets errno to EINTR, and writes the remain‐ ing time into the structure pointed to by rem unless rem is NULL. The value of *rem can then be used to call nanosleep() again and complete the specified pause (but see NOTES). – RaFD Oct 02 '14 at 20:09