简体   繁体   中英

Python server program has high cpu usage

I am experimenting with a python tcp server (I've just recently discovered the awesomeness that is python). Anyway, the server runs just fine and prints data the way I would expect, but when I look at the CPU usage in the windows task manager it shows that python.exe is consuming 97%-99% of the CPU.

Just to see what would happen, I ran it again on a different computer and it only used about 50% of the cpu.

Here is what I am wondering:

  1. Why is the cpu usage so high?

  2. Why would I see a difference running on two different machines (one is Windows 7 the other is server 2008, could that matter)?

  3. I am creating a new thread for each connnection, and running a while loop that is always true, but I have a "break" when there is no longer a connection. Is this thread getting destroyed correctly?

Thanks in advance for any help!

import socket
import threading
import logging
import time

TCP_IP = "127.0.0.1"
TCP_PORT = 10000
BUFFER_SIZE = 1024
SOCKET_TIMEOUT = 2


def handler(conn):
    while 1:
        try:
            data = conn.recv(BUFFER_SIZE)
            if data:
                dataS = data.decode(encoding = 'UTF-8')
                print ("received data: ")
                print (dataS)
                logging.getLogger("TestLogger").critical(dataS)

        except socket.error as e:
            print("connection closed")
            conn.close()
            break

try:    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((TCP_IP, TCP_PORT))
    s.setblocking(0)
    s.listen(5)

except Exception as e:
    print(e)


while 1:
    try:
        conn, addr = s.accept()
    except Exception as e:
        continue
    print ('Connection address:')
    print (addr)
    conn.settimeout(SOCKET_TIMEOUT)
    connThread = threading.Thread(target = handler, args = (conn,))
    connThread.start()

You are using setblocking(0) , that means your socket is not blocking. What you are doing is called polling and will use as much CPU as it can.

When you use threading you don't need to poll. Just remove the setblocking(0) line and it should work properly.

The problem is the infinite while loop (while 1). Please include a few microsecond delay (time.sleep(0.001)), this brings the CPU usage drastically down.

To low reputation to just comment on rsy's answer. In your particular case, when you receive data with "conn.recv", just setting setblocking(1) solves the problem, as pmoleri has answered.

But if you do polling in a loop with "select" statement, just setblocking(1) has no effect and rsy's solution with a short delay (time.delay(0.01)) is the way to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM