By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,125 Members | 1,479 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,125 IT Pros & Developers. It's quick & easy.

Event loop and sleep()

P: n/a
Hi

From what I have understood from various posts in this newsgroup, writing event
loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The problem is that sleep() sleeps at minimum the delay given, but may sleep
longer. Initially I thought this wasn't a problem, until I ran some tests:

On P4/2.6ghz/WinXP, it runs ~500 loops per second ( 2ms avg sleep)
On P4/2.6ghz/Linux 2.6.5, it runs ~250 loops per second ( 3ms avg sleep)
On Cel/400mhz/Linux 2.4.20, it runs ~30 loops per second (20ms avg sleep)

These times were measured with idle event loop, e.g. no events were
posted/handled. On the P4 system, its all good, however I'm concerned about the
30 lps on low-end systems. Since this is idle looping, as soon as I start
posting/handling large amounts of events, it will drop even lower...

I'm not sure, but doesn't that make the app extremely slow? Are there any other
event loop mechanisms besides the above? I did a fair amount of searching over
google but came up pretty emtpy-handed on the topic of writing event loops.
Perhaps someone can suggest a book / website on the topic?

Alo Sarv.
Jul 22 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
Alo Sarv wrote:
Hi

From what I have understood from various posts in this newsgroup, writing event
loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The problem is that sleep() sleeps at minimum the delay given, but may sleep
longer. Initially I thought this wasn't a problem, until I ran some tests:

On P4/2.6ghz/WinXP, it runs ~500 loops per second ( 2ms avg sleep)
On P4/2.6ghz/Linux 2.6.5, it runs ~250 loops per second ( 3ms avg sleep)
On Cel/400mhz/Linux 2.4.20, it runs ~30 loops per second (20ms avg sleep)

These times were measured with idle event loop, e.g. no events were
posted/handled. On the P4 system, its all good, however I'm concerned about the
30 lps on low-end systems. Since this is idle looping, as soon as I start
posting/handling large amounts of events, it will drop even lower...
You are always limited to what your system can handle. Though ony 30
loops per second seems to be rather low unless there are other things
running on that system. It appears that on the slowest system you always
loose a full time-slice, which may happen if another process in
continuosly running at the same priority. What happens if you raise the
thread priority (just for the sake of testing)?

Instead of sleeping you could yield instead since you don't seem to be
interested in getting a certain delay, but only want to be nice to other
threads on the system. To yield use pthread_yield() on POSIX compliant
platforms) or Sleep(0) on Win32. Note that neither sleeping nor yielding
is efficient when the event loop has nothing to do. It still consumes
CPU cycles and causes unnecessary context switches.
I'm not sure, but doesn't that make the app extremely slow? Are there any other
event loop mechanisms besides the above? I did a fair amount of searching over
google but came up pretty emtpy-handed on the topic of writing event loops.
Perhaps someone can suggest a book / website on the topic?


Instead of polling and sleeping in the event loop it would be more
efficient to block the event loop thread until a event has actually
arrived. Depending on the OS you could use condition variables (POSIX)
or Events (Win32) for this. When a event is put into the event queue,
you signal the event loop thread to wake up. When the event loop thread
is awakened it processes all events in the event queue and after that it
waits for another event to arrive in the event queue. The advantage of
this approach is that the event loop doesn't consume CPU cycles when it
has nothing to do.

Note that your question (and my answer) has nothing to do with the C++
language, and therefore is off-topic here. Thing like threads, sleep and
yield functions are not part of the C++ standard. You may want to ask
this question in comp.programming.threads.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 22 '05 #2

P: n/a
Alo Sarv wrote:
From what I have understood from various posts in this newsgroup, writing
event loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The problem is that sleep() sleeps at minimum the delay given, but may
sleep longer. Initially I thought this wasn't a problem, until I ran some
tests:


You can do something like this:

while (true)
{
while (pendingEvents () )
handleEvens ();
sleep (1);
}

--
Salu2
Jul 22 '05 #3

P: n/a
=?ISO-8859-15?Q?Juli=E1n?= Albo posted:
Alo Sarv wrote:
From what I have understood from various posts in this newsgroup,
writing event loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform }

The problem is that sleep() sleeps at minimum the delay given, but may
sleep longer. Initially I thought this wasn't a problem, until I ran
some tests:


You can do something like this:

while (true)
{
while (pendingEvents () )
handleEvens ();
sleep (1);
}


for (;;)
{

}
That way nothing is evalutated.

-JKop
Jul 22 '05 #4

P: n/a
JKop wrote:
You can do something like this:

while (true)
{
while (pendingEvents () )
handleEvens ();
sleep (1);
}

for (;;)
{

}
That way nothing is evalutated.

-JKop


Hi,
"while ( true ) { ... }" should not evaluate anything more than
"for(;;) { ... }". I checked that for g++ on my machine:

// file: for.cc
// ============

#include <iostream>

int main ( void ) {
for (;;) {
std::cout << "0";
}
}

// end of file
// file: while.cc
// ==============

#include <iostream>

int main ( void ) {
while ( true ) {
std::cout << "0";
}
}

// end of file

g++ -S for.cc
g++ -S while.cc
diff for.s while.s 1c1
< .file "for.cc"
--- .file "while.cc"

Best

Kai-Uwe Bux
Jul 22 '05 #5

P: n/a

"Alo Sarv" <al***@hot.ee> wrote in message
news:4a**************************@posting.google.c om...
Hi

From what I have understood from various posts in this newsgroup, writing event loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The problem is that sleep() sleeps at minimum the delay given, but may sleep longer. Initially I thought this wasn't a problem, until I ran some tests:

On P4/2.6ghz/WinXP, it runs ~500 loops per second ( 2ms avg sleep)
On P4/2.6ghz/Linux 2.6.5, it runs ~250 loops per second ( 3ms avg sleep)
On Cel/400mhz/Linux 2.4.20, it runs ~30 loops per second (20ms avg sleep)

These times were measured with idle event loop, e.g. no events were
posted/handled. On the P4 system, its all good, however I'm concerned about the 30 lps on low-end systems. Since this is idle looping, as soon as I start
posting/handling large amounts of events, it will drop even lower...

I'm not sure, but doesn't that make the app extremely slow? Are there any other event loop mechanisms besides the above? I did a fair amount of searching over google but came up pretty emtpy-handed on the topic of writing event loops. Perhaps someone can suggest a book / website on the topic?

Alo Sarv.


You have a few of problems. First, your delay time is arbitrary. Your
times aren't necessarily different because the sleep times are different,
but will also be affected by the time it takes to handle events. If you
have to poll like this, determine the best periodicity for the process, and
implement your code to run at this rate. You have to take into account how
long handleEvents() runs and adjust your sleep time accordingly. For
example, If you decide to make your period 1 Hz, subtract the elapsed time
that handleEvents takes to run from your delay time so you always run at
about 1 Hz.

Another problem is that, depending on your system and needs, poll can be
bad. It wastes processor time and has no regard for other processes. In a
time-slicing environment, this *may* be OK. For a system that uses
cooperative mutli-tasking this is bad. No lower priority thread will be
able to run until your task sleeps.

Third, the time that messages are processed is out of synch. with the
arrival of the messages themselves. This may or may not be OK for your
needs, but it wastes a lot of time sleeping when it has events to process.
To fix this, and the second problem, you need a way to synchronize with your
message flow. If handleEvents can be made to block (go to sleep) until
there are actual events available, then the whole task becomes just loop on
the function call. The task will sleep while there are no events and
automatically wake up when there are some to be handled.

for (;;)
handleEvents();

Regards,

DrX
Jul 22 '05 #6

P: n/a
Alo Sarv wrote:

Hi

From what I have understood from various posts in this newsgroup, writing event
loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The problem is that sleep() sleeps at minimum the delay given, but may sleep
longer. Initially I thought this wasn't a problem, until I ran some tests:

On P4/2.6ghz/WinXP, it runs ~500 loops per second ( 2ms avg sleep)
On P4/2.6ghz/Linux 2.6.5, it runs ~250 loops per second ( 3ms avg sleep)
On Cel/400mhz/Linux 2.4.20, it runs ~30 loops per second (20ms avg sleep)

These times were measured with idle event loop, e.g. no events were
posted/handled. On the P4 system, its all good, however I'm concerned about the
30 lps on low-end systems. Since this is idle looping, as soon as I start
posting/handling large amounts of events, it will drop even lower...

I'm not sure, but doesn't that make the app extremely slow? Are there any other
event loop mechanisms besides the above? I did a fair amount of searching over
google but came up pretty emtpy-handed on the topic of writing event loops.
Perhaps someone can suggest a book / website on the topic?

Alo Sarv.


The simplest thing to do would be to handle events while there are events to
handle, rather than sleeping between each. Presuming that handleEvents()
returns true if an event has been handled, change to:

//...
while (handleEvents()) 0;
// ...
Jul 22 '05 #7

P: n/a
Kai-Uwe Bux wrote:

JKop wrote:
You can do something like this:

while (true)
{
while (pendingEvents () )
handleEvens ();
sleep (1);
}


for (;;)
{

}
That way nothing is evalutated.

-JKop


Hi,

"while ( true ) { ... }" should not evaluate anything more than
"for(;;) { ... }". I checked that for g++ on my machine:

// file: for.cc
// ============

#include <iostream>

int main ( void ) {
for (;;) {
std::cout << "0";
}
}

// end of file

// file: while.cc
// ==============

#include <iostream>

int main ( void ) {
while ( true ) {
std::cout << "0";
}
}

// end of file
g++ -S for.cc
g++ -S while.cc
diff for.s while.s

1c1
< .file "for.cc"
---
.file "while.cc"


Best

Kai-Uwe Bux


for (;;) is the suggested way to define infinite loops, mostly from a
familiarity standpoint. The truth of the matter is that there are a number of
ways to code an infinite loop, and should probably reduce down to the same
underlying machine code.
Jul 22 '05 #8

P: n/a
JKop wrote:
You can do something like this:

while (true)
{
while (pendingEvents () )
handleEvens ();
sleep (1);
}


for (;;)
{

}
That way nothing is evalutated.


If your compiler evaluates something for while (true), change your compiler.

--
Salu2
Jul 22 '05 #9

P: n/a
Julie wrote:
for (;;) is the suggested way to define infinite loops, mostly from a


That dspends on the book you read. Some suggest while (true) istead.

I believe that any programmer with a minimal experience can identify the
intention of both forms, then debate what is better is a lose of time.

--
Salu2
Jul 22 '05 #10

P: n/a
Julie wrote:
Kai-Uwe Bux wrote:

JKop wrote:
>> You can do something like this:
>>
>> while (true)
>> {
>> while (pendingEvents () )
>> handleEvens ();
>> sleep (1);
>> }
>>
>
> for (;;)
> {
>
> }
>
>
> That way nothing is evalutated.
>
> -JKop


Hi,

"while ( true ) { ... }" should not evaluate anything more than
"for(;;) { ... }". I checked that for g++ on my machine:

// file: for.cc
// ============

#include <iostream>

int main ( void ) {
for (;;) {
std::cout << "0";
}
}

// end of file

// file: while.cc
// ==============

#include <iostream>

int main ( void ) {
while ( true ) {
std::cout << "0";
}
}

// end of file
> g++ -S for.cc
> g++ -S while.cc
> diff for.s while.s

1c1
< .file "for.cc"
---
> .file "while.cc"


Best

Kai-Uwe Bux


for (;;) is the suggested way to define infinite loops, mostly from a
familiarity standpoint. The truth of the matter is that there are a
number of ways to code an infinite loop, and should probably reduce down
to the same underlying machine code.


Although I prefer the "while ( true ) { ... }" form, I have no intention to
argue one way or the other. I just wanted to demonstrate that these two
forms should be considered strictly equivalent as there is no performance
penalty involved with either one. It is just a matter of taste.

Am I correct to assume that for(;;) is familiar because it became the
standard idiom for infinite loops in C ?
Best

Kai-Uwe
Jul 22 '05 #11

P: n/a

"Julie" <ju***@nospam.com> wrote in message
news:40***************@nospam.com...
Alo Sarv wrote:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The simplest thing to do would be to handle events while there are events

to handle, rather than sleeping between each. Presuming that handleEvents()
returns true if an event has been handled, change to:

//...
while (handleEvents()) 0;
// ...


Actually, I believe that the purpose of sleep(1) in this kind of event loop
is to reduce the priority of the current process, allowing other processes
to get some time (such as mouse movements, window clicks, etc.). The sleep
call is needed so that the system can respond to user control, for example
to allow the whatever is supposed to break the loop to occur (such as a
mouse click on a Stop button). Failure to add that call results in a loop
that cannot be broken, as events will never get a chance to get into the
event queue.

As stated elsewhere, the loop time depends greatly on the time to actually
handle each event. And since sleep(1) lets other threads/processes get
processor time, the loop delay is also affected by the time given to other
threads/processes, if any. And yes, it *can* cause a program to slow down a
lot, if there are lots of events to handle. But that's the nature of a
multi-tasking environment. And even if it does slow down, you'd be
surprised how much can actually get done in a very short period of time.

I'd be quite suspicious about the times recorded, though, and about the
claim that there was nothing else going on to cause this poor performance
(in the third case). We don't have the code here, or know for sure under
what conditions the test was run, or what the overhead was for setting up
and later exiting the loop, or for getting the time information before and
after the loop ran. Those are all factors to consider when doing timing
tests. (Simply moving the mouse causes the event queue to receive multiple
events!)

-Howard



Jul 22 '05 #12

P: n/a
Howard wrote:

"Julie" <ju***@nospam.com> wrote in message
news:40***************@nospam.com...
Alo Sarv wrote:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The simplest thing to do would be to handle events while there are events

to
handle, rather than sleeping between each. Presuming that handleEvents()
returns true if an event has been handled, change to:

//...
while (handleEvents()) 0;
// ...


Actually, I believe that the purpose of sleep(1) in this kind of event loop
is to reduce the priority of the current process, allowing other processes
to get some time (such as mouse movements, window clicks, etc.). The sleep
call is needed so that the system can respond to user control, for example
to allow the whatever is supposed to break the loop to occur (such as a
mouse click on a Stop button). Failure to add that call results in a loop
that cannot be broken, as events will never get a chance to get into the
event queue.


Right, but the presumption is that there are only a finite number of events to
be handled, and it is typically recommend (if that presumption is the case), to
handle all events at once, and then sleep -- rather than handle one event,
sleep, repeat.

Regardless, this is _all_ very system specific, this is only a general
recommendation on how to handle events and yielding.
As stated elsewhere, the loop time depends greatly on the time to actually
handle each event. And since sleep(1) lets other threads/processes get
processor time, the loop delay is also affected by the time given to other
threads/processes, if any. And yes, it *can* cause a program to slow down a
lot, if there are lots of events to handle. But that's the nature of a
multi-tasking environment. And even if it does slow down, you'd be
surprised how much can actually get done in a very short period of time.

I'd be quite suspicious about the times recorded, though, and about the
claim that there was nothing else going on to cause this poor performance
(in the third case). We don't have the code here, or know for sure under
what conditions the test was run, or what the overhead was for setting up
and later exiting the loop, or for getting the time information before and
after the loop ran. Those are all factors to consider when doing timing
tests. (Simply moving the mouse causes the event queue to receive multiple
events!)


In all reality, it probably has more to do w/ the minimum timeslice provided by
the operating system. Some systems will dynamically change the minimum
timeslice based on the CPU speed. Again, all system specific, and not really
topical here.
Jul 22 '05 #13

P: n/a
"Howard" <al*****@hotmail.com> wrote in message news:<xG*********************@bgtnsc04-news.ops.worldnet.att.net>...
"Julie" <ju***@nospam.com> wrote in message
news:40***************@nospam.com...
Alo Sarv wrote:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}

The simplest thing to do would be to handle events while there are events

to
handle, rather than sleeping between each. Presuming that handleEvents()
returns true if an event has been handled, change to:

//...
while (handleEvents()) 0;
// ...


I considered this, but this causes problems if I have things that I'd like to do
once during each event loop (polling sockets for data for example). The
application I'm writing this for will be having hundreds of open sockets that
need to be polled for data, and the most logical (imho) place to do it would
be once per each event loop.

Actually, I believe that the purpose of sleep(1) in this kind of event loop
is to reduce the priority of the current process, allowing other processes
to get some time (such as mouse movements, window clicks, etc.). The sleep
call is needed so that the system can respond to user control, for example
to allow the whatever is supposed to break the loop to occur (such as a
mouse click on a Stop button). Failure to add that call results in a loop
that cannot be broken, as events will never get a chance to get into the
event queue.

As stated elsewhere, the loop time depends greatly on the time to actually
handle each event. And since sleep(1) lets other threads/processes get
processor time, the loop delay is also affected by the time given to other
threads/processes, if any. And yes, it *can* cause a program to slow down a
lot, if there are lots of events to handle. But that's the nature of a
multi-tasking environment. And even if it does slow down, you'd be
surprised how much can actually get done in a very short period of time.

I'd be quite suspicious about the times recorded, though, and about the
claim that there was nothing else going on to cause this poor performance
(in the third case). We don't have the code here, or know for sure under
what conditions the test was run, or what the overhead was for setting up
and later exiting the loop, or for getting the time information before and
after the loop ran. Those are all factors to consider when doing timing
tests. (Simply moving the mouse causes the event queue to receive multiple
events!)


A more simplified test code which shows this issue goes as follows (unix only)

#include "StopWatch.h"
#include <unistd.h>
#include <iostream>
int main() {
while (true) {
StopWatch s1;
usleep(1);
std::cerr << "Sleep length: " << s1.Time() << std::endl;
}
}

StopWatch is a small time-measuring class which uses gettimeofday() (unix) to
measure the difference of times. This code shows 15-20ms sleeps. Oddly enough,
system load doesn't seem to affect how many loops were ran - idle and full load
had no effect on the sleep lengths. However, increasing the work done in the loop
itself did (as was expected). Creating 200 open network connections and polling
each of them for data during each loop dropped loops-per-sec from 500 to 5 on the
P4 system / winXP. Question is how does it affect the application's performance
in real life situation...

Alo Sarv.
Jul 22 '05 #14

P: n/a
"Alo Sarv" <al***@hot.ee> wrote
Hi

From what I have understood from various posts in this newsgroup, writing event
loops pretty much comes down to this:

while (true) {
handleEvents();
sleep(1); // or _sleep() or nanosleep(), depending on platform
}
There's no reason whatsoever to have a sleep() in there. On any but the most
absurdly written event-handling libraries, either the operation that gets an
event is a blocking call, or the event multiplexer is. The loop should simply be
getEvent/handleEvent with no arbitrary delay between the two.

[... irrelevant discussion of the semantics of sleep deleted ...]
Perhaps someone can suggest a book / website on the topic?


Practically all of the late Richard Stevens' books have discussions on this.

Claudio Puviani
Jul 22 '05 #15

P: n/a

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
"Alo Sarv" <al***@hot.ee> wrote

There's no reason whatsoever to have a sleep() in there. On any but the most absurdly written event-handling libraries, either the operation that gets an event is a blocking call, or the event multiplexer is. The loop should simply be getEvent/handleEvent with no arbitrary delay between the two.


Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without the
sleep there (at least on Windows, which you might be referring to as one of
those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without the
sleep in a Windows system (if you've got one), and you should be able to see
what I mean. (I don't have any idea about other systems, though.)

-Howard
Jul 22 '05 #16

P: n/a
Howard wrote:

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
"Alo Sarv" <al***@hot.ee> wrote

There's no reason whatsoever to have a sleep() in there. On any but the

most
absurdly written event-handling libraries, either the operation that gets

an
event is a blocking call, or the event multiplexer is. The loop should

simply be
getEvent/handleEvent with no arbitrary delay between the two.


Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without the
sleep there (at least on Windows, which you might be referring to as one of
those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without the
sleep in a Windows system (if you've got one), and you should be able to see
what I mean. (I don't have any idea about other systems, though.)

-Howard


You didn't follow his reasoning.

In this case, the handleEvent call should:
- process any pending events
or
- block (sleep, yield, etc.) until there is an event

Under windows, the GetMessage() call *does* the above -- it either gets a
message (to be subsequently processed), or it blocks until there is a message.

There should be no need for a Sleep call in an event handler loop in most
circumstances -- that should all be handled within the get/handle/dispatch
event code.

Get it?
Jul 22 '05 #17

P: n/a

"Howard" <al*****@hotmail.com> wrote in message
news:Ye********************@bgtnsc04-news.ops.worldnet.att.net...

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
"Alo Sarv" <al***@hot.ee> wrote

There's no reason whatsoever to have a sleep() in there. On any but the most
absurdly written event-handling libraries, either the operation that

gets an
event is a blocking call, or the event multiplexer is. The loop should simply be
getEvent/handleEvent with no arbitrary delay between the two.


Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without the
sleep there (at least on Windows, which you might be referring to as one

of those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without the
sleep in a Windows system (if you've got one), and you should be able to see what I mean. (I don't have any idea about other systems, though.)

-Howard


sleep does not change the priority of a process in Window, nor in any other
system I know of.

DrX
Jul 22 '05 #18

P: n/a

"Julie" <ju***@nospam.com> wrote in message
news:40***************@nospam.com...
Howard wrote:

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
"Alo Sarv" <al***@hot.ee> wrote

There's no reason whatsoever to have a sleep() in there. On any but
the most
absurdly written event-handling libraries, either the operation that
gets an
event is a blocking call, or the event multiplexer is. The loop should simply be
getEvent/handleEvent with no arbitrary delay between the two.


Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without the
sleep there (at least on Windows, which you might be referring to as one of those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without the sleep in a Windows system (if you've got one), and you should be able to see what I mean. (I don't have any idea about other systems, though.)

-Howard


You didn't follow his reasoning.

In this case, the handleEvent call should:
- process any pending events
or
- block (sleep, yield, etc.) until there is an event

Under windows, the GetMessage() call *does* the above -- it either gets a
message (to be subsequently processed), or it blocks until there is a

message.
There should be no need for a Sleep call in an event handler loop in most
circumstances -- that should all be handled within the get/handle/dispatch
event code.

Get it?


Ah, got it. I may have been thinking of using PeekMessage, not GetMessage.
PeekMessage doesn't wait on events, it just checks if they exist. (And
since he doesn't describe the contents of handleEvents, I just made an
assumption, based on how I've written similar code in the past.) I just
checked GetMessage on the MSDN site, and it seems that you are correct that
system time will be released during the "wait" for incoming events.

Just to follow up on the sleep function though, the docs on MSDN say that
using sleep(0) will release the remainder of the current time slice,
allowing time for other threads of equal priority to process. Using
sleep(1) was done so that everyobdy got a chance to process their stuff
without significantly delaying the current thread. So if you're simply
polling, and not waiting as GetMessage does, it's a good thing to have
there. But apparently uneccessary with GetMessage. (And to be honest, I
never wrote such a loop in C++, only in Delphi, and damned if I know exactly
how their Application.ProcessMessages function relates to the direct Windows
API calls GetMessage or PeekMessage!)

Thanks for the clarification.

-Howard

Jul 22 '05 #19

P: n/a
"Xenos" <do**********@spamhate.com> wrote in message news:<cc*********@cui1.lmms.lmco.com>...
"Howard" <al*****@hotmail.com> wrote in message
news:Ye********************@bgtnsc04-news.ops.worldnet.att.net...

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
"Alo Sarv" <al***@hot.ee> wrote

There's no reason whatsoever to have a sleep() in there. On any but the most absurdly written event-handling libraries, either the operation that gets
an event is a blocking call, or the event multiplexer is. The loop should simply be getEvent/handleEvent with no arbitrary delay between the two.


Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without the
sleep there (at least on Windows, which you might be referring to as one

of
those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without the
sleep in a Windows system (if you've got one), and you should be able to

see
what I mean. (I don't have any idea about other systems, though.)

-Howard


sleep does not change the priority of a process in Window, nor in any other
system I know of.

DrX


I think I failed to make my intentions clear, so let me clarify:

The application is singlethreaded, all events are received from
sockets. The purpose of sleep() was to wake up at some interval, check
if there is anything to process from sockets, and then go back to
sleep. I don't see a way to make the system blocking without coupling
event engine directly with sockets. Additionally, there might pending
jobs that take long time (checksumming files for example), that should
be done in small amounts (64k blocks for example) during event loops.
Or there could be jobs that need to be done at specific intervals (for
example, autosaving config file every 20 minutes). Thus blocking
the loop if there are no socket events isn't an option, since that
would also block those jobs. Removing the sleep() from the loop causes
the loop to run as fast as possible, thus using 100% CPU (on any
system/compiler).

One option that was pointed out in this thread was to loop around
until there are events to process, and then go to sleep for a minimum
delay. Now, if an event handler function posts a new event, that event
also needs to be processed. And if a handler for the new event also
posts a event, that one also needs to be processed, thus can cause
endless loop if the user of the event system isn't careful... Ok, this
could be countered by limiting the number of runs through event loop
w/o sleeping to some amount, after which a sleep will be forced. Can't
say I'm exactly thrilled with this solution.

Alo.
Jul 22 '05 #20

P: n/a
"Xenos" <do**********@spamhate.com> wrote in message news:<cc*********@cui1.lmms.lmco.com>...
"Howard" <al*****@hotmail.com> wrote in message
news:Ye********************@bgtnsc04-news.ops.worldnet.att.net...

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
"Alo Sarv" <al***@hot.ee> wrote

There's no reason whatsoever to have a sleep() in there. On any but the most absurdly written event-handling libraries, either the operation that gets
an event is a blocking call, or the event multiplexer is. The loop should simply be getEvent/handleEvent with no arbitrary delay between the two.


Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without the
sleep there (at least on Windows, which you might be referring to as one

of
those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without the
sleep in a Windows system (if you've got one), and you should be able to

see
what I mean. (I don't have any idea about other systems, though.)

-Howard


sleep does not change the priority of a process in Window, nor in any other
system I know of.

DrX


I think I failed to make my intentions clear, so let me clarify:

The application is singlethreaded, all events are received from
sockets. The purpose of sleep() was to wake up at some interval, check
if there is anything to process from sockets, and then go back to
sleep. I don't see a way to make the system blocking without coupling
event engine directly with sockets. Additionally, there might pending
jobs that take long time (checksumming files for example), that should
be done in small amounts (64k blocks for example) during event loops.
Or there could be jobs that need to be done at specific intervals (for
example, autosaving config file every 20 minutes). Thus blocking
the loop if there are no socket events isn't an option, since that
would also block those jobs. Removing the sleep() from the loop causes
the loop to run as fast as possible, thus using 100% CPU (on any
system/compiler).

One option that was pointed out in this thread was to loop around
until there are events to process, and then go to sleep for a minimum
delay. Now, if an event handler function posts a new event, that event
also needs to be processed. And if a handler for the new event also
posts a event, that one also needs to be processed, thus can cause
endless loop if the user of the event system isn't careful... Ok, this
could be countered by limiting the number of runs through event loop
w/o sleeping to some amount, after which a sleep will be forced. Can't
say I'm exactly thrilled with this solution.

Alo.
Jul 22 '05 #21

P: n/a

"Alo Sarv" <al***@hot.ee> wrote in message
news:4a**************************@posting.google.c om...
"Xenos" <do**********@spamhate.com> wrote in message

news:<cc*********@cui1.lmms.lmco.com>...
"Howard" <al*****@hotmail.com> wrote in message
news:Ye********************@bgtnsc04-news.ops.worldnet.att.net...

"Claudio Puviani" <pu*****@hotmail.com> wrote in message
news:_9**********************@news4.srv.hcvlny.cv. net...
> "Alo Sarv" <al***@hot.ee> wrote
>
> There's no reason whatsoever to have a sleep() in there. On any but the
most
> absurdly written event-handling libraries, either the operation that

gets
an
> event is a blocking call, or the event multiplexer is. The loop
should simply be
> getEvent/handleEvent with no arbitrary delay between the two.
>

Yes, there is a reason. It's put there to reduce the priority of the
process such that other processes can run their event loops. Without
the sleep there (at least on Windows, which you might be referring to as one of
those absurdly-written libraries(?)), the loop hogs all the processing
power, making the system unresponsive. Try the loop with and without
the sleep in a Windows system (if you've got one), and you should be able

to see
what I mean. (I don't have any idea about other systems, though.)

-Howard


sleep does not change the priority of a process in Window, nor in any other system I know of.

DrX


I think I failed to make my intentions clear, so let me clarify:

The application is singlethreaded, all events are received from
sockets. The purpose of sleep() was to wake up at some interval, check
if there is anything to process from sockets, and then go back to
sleep. I don't see a way to make the system blocking without coupling
event engine directly with sockets. Additionally, there might pending
jobs that take long time (checksumming files for example), that should
be done in small amounts (64k blocks for example) during event loops.
Or there could be jobs that need to be done at specific intervals (for
example, autosaving config file every 20 minutes). Thus blocking
the loop if there are no socket events isn't an option, since that
would also block those jobs. Removing the sleep() from the loop causes
the loop to run as fast as possible, thus using 100% CPU (on any
system/compiler).

One option that was pointed out in this thread was to loop around
until there are events to process, and then go to sleep for a minimum
delay. Now, if an event handler function posts a new event, that event
also needs to be processed. And if a handler for the new event also
posts a event, that one also needs to be processed, thus can cause
endless loop if the user of the event system isn't careful... Ok, this
could be countered by limiting the number of runs through event loop
w/o sleeping to some amount, after which a sleep will be forced. Can't
say I'm exactly thrilled with this solution.

Alo.


Although this thread is a bit off-topic, there are many more ways to make a
thread block then just sockets. As someone suggested, the message queue
itself can cause the thread to block when its empty. If that's not already
a property of the queue, the funtionally can be achieved by wrapping the
read of the queue with the taking of a semaphore, and the write with the
giving the semaphore (text book reader-writer mechanism). Artifically
blocking via delays is, in my humble opinion usually bad. The event to be
handled is decoupled and asynchronous to the thead of execution that is
process it. It is always best if the two can be tied together so that it's
the event the awakens the task. The task will not waste time sleeping when
there are events to process and it will not waste the processor polling for
events when they are not there.

Jul 22 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.