[Spread-users] Spread python poll() taking almost 100% CPU

Tim Peters tim.peters at gmail.com
Fri Oct 1 16:52:49 EDT 2004

[Baillargeon, Sonny]
> I am a noob to spread but find it works great.  I am using the python
> module 1.4 with spread 3.17.2 and python 2.3.4 on Solaris 8.
> I wrote a quick little spread listner.  I run 2 spread servers per
> segment and currently I am testing with 2 segments.
> The problem is the spread listener is taking up close to 100% CPU when I
> run the listener.  The python code is:
> 8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<
> #!/usr/bin/env python
> # Spread server proof of concept
> ...
> mbox = spread.connect(spreadName, group, 0, 1)
> mbox.join(group)
> while 1:
>    if mbox.poll():
>        msg = mbox.receive()
> ...
> Is there a better way of listen for spread messages?  Is the poll()
> causing my cpu issue?

poll() isn't expensive, but you never give it a rest.  So this is like
asking whether addition is causing your CPU problem in:

    while 1:
        k = 1 + 2

Well, no, it's not really addition that's giving you grief <wink>.

It's unclear why you're calling poll() here, because your "if" didn't
have an "else" clause.  If all you want to do is sit and wait for the
next message to come in, get rid of the poll(), and simply do:

    msg = mbox.receive()

That will block efficiently until a message is available.

If, unlike as in the code you posted, you actually want to do
something else if a message isn't available, you could, e.g., put a
time.sleep() call at the top of the loop, before the poll(), waiting
for as long as you're willing to wait between instances of "doing
something else".

I recommend never using poll(), though.  If Spread disconnects your
client, poll() doesn't tell you -- poll() just keeps saying "nope, no
messages" then.  At least that was true last time I tested it, and I
haven't used poll() since.

The industrial-strength approach to mixing waiting for messages and
"doing something else" is to use a socket select(), a la:

    mbox = spread.connect(...)
    while 1:
        r, w, x = select.select([mbox.fileno()], [], [], 1.5)
        if r:
            msg = mbox.receive()
            # process the message
            # 1.5 seconds elapsed went by without seeing a msg.
            # Do something else.

You'll be happy with that; or, if you don't want to do anything other
than get msgs, just do a straight:

    msg = mbox.receive()

and let it worry about figuring out when a msg is available.

More information about the Spread-users mailing list