Question about busy waiting

S

stevengarcia

I've got a question about busy waiting. Our application controls
hardware devices via the serial port, so we are constantly writing
commands to the devices via an OutputStream, and reading the responses
from an InputStream.

I'm looking at a block of code in my codebase and it's doing the
following:

public String read(InputStream in) throws IOException {
while (in.available() <= 0) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
log.warn("Thread was interupted while sleeping", e);
}
}
...
// read from input stream...
}

The reason why the code is waiting is that the InputStream that we get
from the underlying serial port library (javax.comm) doesn't implement
InputStream properly, and it's recommended that we call in.available()
until there is actually some data available to read.

To prevent a busy wait that consumes the entire CPU, the code sleeps
for 10 ms (a very short period of time.) I've watched the CPU and it
doesn't appear pegged when this code runs.

My question is whether you think this is an effective way of avoiding
the "busy wait" problem by only sleeping for just 10ms? I would think
that the CPU would still go crazy if it only had to sleep for 10 ms.
Any opinions on this?
 
M

Mike Schilling

I've got a question about busy waiting. Our application controls
hardware devices via the serial port, so we are constantly writing
commands to the devices via an OutputStream, and reading the responses
from an InputStream.

I'm looking at a block of code in my codebase and it's doing the
following:

public String read(InputStream in) throws IOException {
while (in.available() <= 0) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
log.warn("Thread was interupted while sleeping", e);
}
}
...
// read from input stream...
}

The reason why the code is waiting is that the InputStream that we get
from the underlying serial port library (javax.comm) doesn't implement
InputStream properly, and it's recommended that we call in.available()
until there is actually some data available to read.

To prevent a busy wait that consumes the entire CPU, the code sleeps
for 10 ms (a very short period of time.) I've watched the CPU and it
doesn't appear pegged when this code runs.

My question is whether you think this is an effective way of avoiding
the "busy wait" problem by only sleeping for just 10ms? I would think
that the CPU would still go crazy if it only had to sleep for 10 ms.
Any opinions on this?

10 milliseconds is an eternity to a modern CPU, so I wouldn't worry too much
about the load on the system. In fact, I'd worry more about the effect on
throughput from waiting so long.

It would be neater to have more explicit synchronization, but if the library
you're using doesn't supply it, this is about the best you can do.
 
K

Knute Johnson

I've got a question about busy waiting. Our application controls
hardware devices via the serial port, so we are constantly writing
commands to the devices via an OutputStream, and reading the responses
from an InputStream.

I'm looking at a block of code in my codebase and it's doing the
following:

public String read(InputStream in) throws IOException {
while (in.available() <= 0) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
log.warn("Thread was interupted while sleeping", e);
}
}
...
// read from input stream...
}

The reason why the code is waiting is that the InputStream that we get
from the underlying serial port library (javax.comm) doesn't implement
InputStream properly, and it's recommended that we call in.available()
until there is actually some data available to read.

To prevent a busy wait that consumes the entire CPU, the code sleeps
for 10 ms (a very short period of time.) I've watched the CPU and it
doesn't appear pegged when this code runs.

My question is whether you think this is an effective way of avoiding
the "busy wait" problem by only sleeping for just 10ms? I would think
that the CPU would still go crazy if it only had to sleep for 10 ms.
Any opinions on this?

Are you using a really old version of the JavaComm API? I've not had
any problems with it and I've been using it for 5 or 6 years. I just
finished an app that is read only but it is working fine. And I wrote
an extensive one a few years ago that reads and writes. My experience
is under Windows.
 
R

Remon van Vliet

I've got a question about busy waiting. Our application controls
hardware devices via the serial port, so we are constantly writing
commands to the devices via an OutputStream, and reading the responses
from an InputStream.

I'm looking at a block of code in my codebase and it's doing the
following:

public String read(InputStream in) throws IOException {
while (in.available() <= 0) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
log.warn("Thread was interupted while sleeping", e);
}
}
...
// read from input stream...
}

The reason why the code is waiting is that the InputStream that we get
from the underlying serial port library (javax.comm) doesn't implement
InputStream properly, and it's recommended that we call in.available()
until there is actually some data available to read.

To prevent a busy wait that consumes the entire CPU, the code sleeps
for 10 ms (a very short period of time.) I've watched the CPU and it
doesn't appear pegged when this code runs.

My question is whether you think this is an effective way of avoiding
the "busy wait" problem by only sleeping for just 10ms? I would think
that the CPU would still go crazy if it only had to sleep for 10 ms.
Any opinions on this?

As far as i'm aware it supports a blocking read just fine and you shouldnt
have to wait for in.available() > 0. Are you sure that recommendation you're
following is actually valid?

Remon van Vliet
 
S

stevengarcia

We are using the previous javax.comm version (not the current one which
I think is v2.0) because the newest one doesn't have a driver for
Windows (yet.)

I'm aware of the blocking read, and the other settings on CommPort that
configure how the InputStream reads bytes. The reason why they are
insufficient in some cases for this project is that we are talking to
dozens (and in the future 100's) of hardware devices (monitors,
projectors, switches, routers, cameras, lighting equipment, etc.) that
all act diffferently. Some devices decide to send their responses to a
command immediately, and every byte is sent immediately. Some decide
to wait 50 ms and then send all of their bytes. Others decide to send
bytes in little chunks at a time over 2000 ms, thereby making the code

while (in.available() > 0) {
in.read()...
}

not wholly reliable because in.available() will return 0 at several
invocations within that 2000 ms. Even further, the responses are not
consistent for each device i.e. two commands might produce two
different types of response from the same device.

The other aspect is performance...we could easily set a blocking read
to be 5000ms for every single device and command, and this would bring
our system down to a halt. If we have n devices, m commands per
device, and 5000 ms per command, then we have total communication time
of 5mn. This can be quite large in practice. We routinely control a
couple dozen devices and each device, on average, supports 4 commands.
So 5 x 24 x 4 = 480 s, or 8 minutes per refresh of our system.

(Of course we can multi-thread the refresh command and that would
significantly cut into our time, but we need the refresh to take 5-10
seconds, and multi-threading wouldn't do that).

So the functionality we need is to "read from the input stream until we
get all the bytes we expect." Most of the time a simple, one time read
from the InputStream is sufficient. But we have some number of devices
where one read won't work, we need to read continuously until a certain
condition is met. Hence I want to try to avoid busy waiting.

Given this, is there material benefit over the length of time one
sleeps to avoid busy waiting? Or do the three statements below all
equally free up CPU usage with respect to avoiding busy waiting?

Thread.sleep(1)
Thread.sleep(10)
Thread.sleep(100)
 
K

Knute Johnson

We are using the previous javax.comm version (not the current one which
I think is v2.0) because the newest one doesn't have a driver for
Windows (yet.)

I'm aware of the blocking read, and the other settings on CommPort that
configure how the InputStream reads bytes. The reason why they are
insufficient in some cases for this project is that we are talking to
dozens (and in the future 100's) of hardware devices (monitors,
projectors, switches, routers, cameras, lighting equipment, etc.) that
all act diffferently. Some devices decide to send their responses to a
command immediately, and every byte is sent immediately. Some decide
to wait 50 ms and then send all of their bytes. Others decide to send
bytes in little chunks at a time over 2000 ms, thereby making the code

while (in.available() > 0) {
in.read()...
}

not wholly reliable because in.available() will return 0 at several
invocations within that 2000 ms. Even further, the responses are not
consistent for each device i.e. two commands might produce two
different types of response from the same device.

The other aspect is performance...we could easily set a blocking read
to be 5000ms for every single device and command, and this would bring
our system down to a halt. If we have n devices, m commands per
device, and 5000 ms per command, then we have total communication time
of 5mn. This can be quite large in practice. We routinely control a
couple dozen devices and each device, on average, supports 4 commands.
So 5 x 24 x 4 = 480 s, or 8 minutes per refresh of our system.

(Of course we can multi-thread the refresh command and that would
significantly cut into our time, but we need the refresh to take 5-10
seconds, and multi-threading wouldn't do that).

So the functionality we need is to "read from the input stream until we
get all the bytes we expect." Most of the time a simple, one time read
from the InputStream is sufficient. But we have some number of devices
where one read won't work, we need to read continuously until a certain
condition is met. Hence I want to try to avoid busy waiting.

Given this, is there material benefit over the length of time one
sleeps to avoid busy waiting? Or do the three statements below all
equally free up CPU usage with respect to avoiding busy waiting?

Thread.sleep(1)
Thread.sleep(10)
Thread.sleep(100)

I don't understand why if you are so concerned about getting your data
immediately you want to wait for it. It doesn't make any sense. If you
have hundreds of ports to check for data then you don't have time to
wait around. You really haven't given us enough information about your
system architecture to tell you what to do but I can almost guarantee
you that busy waiting is not the answer. What kind of computer is going
to support hundreds of real rs-232 ports anyway? Most likely you will
have to have some sort of multi serial port cards and they will have
drivers to make all of the serial i/o transparent.

I think you need to write code specific to the device and multi-thread
reading the responses. Asynchronous processes need to be dealt with
asynchronously. Create a class that handles I/O for a specific device
type and pass status messages back and forth. Windows will handle
dozens of threads and if you need hundreds you will probably have to go
to Linux or some other OS.
 
S

stevengarcia

Knute said:
I don't understand why if you are so concerned about getting your data
immediately you want to wait for it. It doesn't make any sense. If you

I want to get the data as soon as the device sends it to me. That
could be 10ms after I send the device a command, it could be 100ms, it
could be 2000ms. And it could start sending data 10ms after the
command was issues, and send a total of 120 bytes in 2000 ms.
have hundreds of ports to check for data then you don't have time to
wait around. You really haven't given us enough information about your
system architecture to tell you what to do but I can almost guarantee
you that busy waiting is not the answer. What kind of computer is going
to support hundreds of real rs-232 ports anyway? Most likely you will

Let's just take one device at a time. I assume you are familiar with
the javax.comm API. Suppose you want to send a device three
commands, and two of them return *about* 30 bytes in 100ms, and one
command returns *about* 120 bytes in 2000ms. I say *about* because it
depends on the nature of the response (e.g. if you ask a plasma monitor
what video input select its on, it could return different codes for
DVI, SVideo, RGB, Composite, and those codes can be different length.
So we can't be sure).

How would you write this?

Just solving this case, this and only this, would be fairly trivial.
But we get this kind of erratic response from dozens of different
devices.

BTW, there are Serial-to-IP converters that allow one computer to talk
to hundreds of serial ports at the same time, over IP. We have port
addresses going up to COM 135, for instance.
have to have some sort of multi serial port cards and they will have
drivers to make all of the serial i/o transparent.

I think you need to write code specific to the device and multi-thread
reading the responses. Asynchronous processes need to be dealt with
asynchronously. Create a class that handles I/O for a specific device
type and pass status messages back and forth. Windows will handle
dozens of threads and if you need hundreds you will probably have to go
to Linux or some other OS.

We are basically writing an application to do this. Is it possible to
talk about busy waiting without respect to this particular problem?
Suppose I said that you are going to read from an input stream, and it
erratically providss bytes to be read with no rhyme or reason. You
can't rely on in.available() because it's wrong. Yea, this is a crappy
implementation of InputStream but we are stuck with it. Thus my
original question...Is there material benefit over the length of time
one sleeps to avoid busy waiting? Or do the three statements below all
equally free up CPU usage with respect to avoiding busy waiting?

Thread.sleep(1)
Thread.sleep(10)
Thread.sleep(100)

I hope this makes sense.
 
K

Knute Johnson

I want to get the data as soon as the device sends it to me. That
could be 10ms after I send the device a command, it could be 100ms, it
could be 2000ms. And it could start sending data 10ms after the
command was issues, and send a total of 120 bytes in 2000 ms.


Let's just take one device at a time. I assume you are familiar with
the javax.comm API. Suppose you want to send a device three
commands, and two of them return *about* 30 bytes in 100ms, and one
command returns *about* 120 bytes in 2000ms. I say *about* because it
depends on the nature of the response (e.g. if you ask a plasma monitor
what video input select its on, it could return different codes for
DVI, SVideo, RGB, Composite, and those codes can be different length.
So we can't be sure).

How would you write this?

Just solving this case, this and only this, would be fairly trivial.
But we get this kind of erratic response from dozens of different
devices.

BTW, there are Serial-to-IP converters that allow one computer to talk
to hundreds of serial ports at the same time, over IP. We have port
addresses going up to COM 135, for instance.


We are basically writing an application to do this. Is it possible to
talk about busy waiting without respect to this particular problem?
Suppose I said that you are going to read from an input stream, and it
erratically providss bytes to be read with no rhyme or reason. You
can't rely on in.available() because it's wrong. Yea, this is a crappy
implementation of InputStream but we are stuck with it. Thus my
original question...Is there material benefit over the length of time
one sleeps to avoid busy waiting? Or do the three statements below all
equally free up CPU usage with respect to avoiding busy waiting?

Thread.sleep(1)
Thread.sleep(10)
Thread.sleep(100)

I hope this makes sense.

If the only question is; I have to busy wait, how long should I wait?
The only answer can be, as short a time as possible.

I still wouldn't do it that way though if performance is an issue. I
would write device specific classes that handle the command/answer with
the device and post an event or message or set a status flag. The comm
drivers have the capability to post an event when data is available,
they can block until a number of bytes is read or block until a certain
amount of time has elapsed. Or you can multi-thread and read data when
it is available and act on it immediately.

You have to know when you have read the complete response from the
device, read until that happens and then process the data. It doesn't
matter how long the message is or how long it takes to read it. Even if
these ports were IP to serial cards you wouldn't want to busy wait on
them. Which brings up a point, if you are going to use one of those
cards you won't need the JavaComm API. They present a stream that you
just read and write to. You could use the non-blocking new IO API but I
still wouldn't busy wait.
 
C

Chris Uppal

BTW, there are Serial-to-IP converters that allow one computer to talk
to hundreds of serial ports at the same time, over IP. We have port
addresses going up to COM 135, for instance.

Then why not use one of those, and use Java's nio stuff to read all the inputs
asynchonously with no busy waiting at all ? Seems to me that easily beats
messing around with javax.comm.

-- chris
 
N

neuneudr

Knute Johnson wrote:
....
I don't understand why if you are so concerned about getting your data
immediately you want to wait for it. It doesn't make any sense. If you
have hundreds of ports to check for data then you don't have time to
wait around. You really haven't given us enough information about your
system architecture to tell you what to do but I can almost guarantee
you that busy waiting is not the answer.

If the OP is calling Thread.sleep(10), he is *not* busy-waiting.

It looks like you're confused as to what the term
"busy-waiting" means.

http://en.wikipedia.org/wiki/Busy_waiting

A thread sleeping for 10 ms, on a modern CPU executing billions
of cycles per second, leaves *plenty* of time to the other threads.

Joshua Bloch explain very nicely what is busy waiting in his
Effective Java book and clearly states that adding Thread.sleep(...)
turns a busy-waiting thread in a *non* busy-waiting thread:

Joshua Bloch, Effective Java, Item 51 (page 151)
 
N

neuneudr

Chris Uppal wrote:
....
Then why not use one of those, and use Java's nio stuff to read all the inputs
asynchonously with no busy waiting at all ?
^^^^^^^^^^^^

If the OP is calling Thread.sleep(10), he is *not* busy-waiting.

It looks like you're confused as to what the term
"busy-waiting" means.

http://en.wikipedia.org/wiki/Busy_waiting

A thread sleeping for 10 ms, on a modern CPU executing billions
of cycles per second, leaves *plenty* of time to the other threads.

Joshua Bloch explain very nicely what is busy waiting in his
Effective Java book and clearly states that adding Thread.sleep(...)
turns a busy-waiting thread in a *non* busy-waiting thread:

Joshua Bloch, Effective Java, Item 51 (page 151)
 
C

Chris Uppal

If the OP is calling Thread.sleep(10), he is *not* busy-waiting.

If he's polling every 1 or 10 milliseconds then that's busy waiting in /my/
book.

-- chris
 
N

neuneudr

Chris said:
If he's polling every 1 or 10 milliseconds then that's busy waiting in /my/
book.

Which was *exactly* my point: your book is wrong. Hence the
Wikipedia link and the very precise reference to Joshua Bloch's book.

If it helps you to have your own book with your own definitions
so they fits your view of the world, fine.

You can find Thread.sleep(10) fugly code, that's fine. But do not
call it busy-waiting for it is not busy-waiting.

I'd rather use Joshua Bloch's Effective Java book definition than
yours... Or
the one given at Wikipedia (not that everything at Wikipedia is
correct).

You could run a simple example and see a thread *really* busy-waiting
"pegging the CPU", like the OP said.

Now you could add a Thread.sleep(10) and see that same example
run without any problem (the system won't appear to be slowling to
a crawl). For busy-waiting is a very specific technique (sometimes
useful, but that is another topic) with a well defined behavior.

I stand by what I said: Wikipedia's definition is correct, the OP's
definition is correct, Joshua Bloch's definition is correct.

Yours is wrong... And you decide to stand by it, fine. But you're
trying
to spread misconception and I hope people will be more enclined to
read Joshua Bloch's book than yours.
 
N

neuneudr

Is there material benefit over the length of time
one sleeps to avoid busy waiting? Or do the three statements below all
equally free up CPU usage with respect to avoiding busy waiting?

Thread.sleep(1)
Thread.sleep(10)
Thread.sleep(100)

You're correct that these three statements avoid busy-waiting. It may
not be efficient, it may not be nice, but it is *not* called
busy-waiting
as long as you're calling Thread.sleep() (and the way your question
is formulated makes it clear you've got the definition of busy-waiting
right).

I hope this makes sense.

You're question makes perfect sense and is perfectly formulated, but
as you can see you'll have trouble getting an answer to this here as
people are more busy re-defining the meaning of busy-waiting than
actually trying to answer that specific question you asked twice...
 
R

Remon van Vliet

Knute Johnson wrote:
...

If the OP is calling Thread.sleep(10), he is *not* busy-waiting.

It looks like you're confused as to what the term
"busy-waiting" means.

http://en.wikipedia.org/wiki/Busy_waiting

A thread sleeping for 10 ms, on a modern CPU executing billions
of cycles per second, leaves *plenty* of time to the other threads.

Joshua Bloch explain very nicely what is busy waiting in his
Effective Java book and clearly states that adding Thread.sleep(...)
turns a busy-waiting thread in a *non* busy-waiting thread:

Joshua Bloch, Effective Java, Item 51 (page 151)

First of all, it's semantics, you know what he meant. Second of all, authors
of books arent omnipotent, even if they have worked for Sun. Busy-waits are
most commonly defined as loops that do nothing else but wait for their loop
condition to become false. Granted, it can be argued that sleeping or
yielding in such a loop is not "doing nothing", but i'd disagree with people
claiming that as would many other developers. Also, such loops giving other
threads time doesnt disqualify them as a busy-wait loop, all loops in a
proper multi-threaded environment do that whether you want them to or not.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,163
Latest member
Sasha15427
Top