Python服务器程序CPU使用率高

7 投票
3 回答
6701 浏览
提问于 2025-04-18 07:26

我正在尝试搭建一个Python的TCP服务器(我最近才发现Python真是太棒了)。总之,服务器运行得很好,输出的数据也和我预期的一样,但当我在Windows任务管理器中查看CPU使用情况时,发现python.exe的CPU使用率竟然高达97%-99%。

为了看看会发生什么,我在另一台电脑上重新运行了一遍,结果它的CPU使用率只有大约50%。

我在想以下几个问题:

  1. 为什么CPU使用率这么高?

  2. 为什么在两台不同的机器上运行会有差别(一个是Windows 7,另一个是Server 2008,这会有影响吗)?

  3. 我为每个连接创建了一个新的线程,并且在运行一个永远为真的循环,但当没有连接时我有一个“break”来退出。这个线程会被正确销毁吗?

提前感谢任何帮助!

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()

3 个回答

2

因为声望太低,不能直接评论rsy的回答。
在你的具体情况下,当你用“conn.recv”接收数据时,简单地设置setblocking(1)就能解决问题,正如pmoleri所说的那样。

但是如果你在一个循环中使用“select”语句进行轮询,仅仅设置setblocking(1)是没用的,这时候rsy提到的加一个短暂的延迟(time.delay(0.01))才是正确的做法。

4

问题出在这个无限循环上(while 1)。请加上一点微小的延迟(time.sleep(0.001)),这样可以大大降低CPU的使用率。

6

你正在使用 setblocking(0),这意味着你的网络连接是非阻塞的。你现在做的事情叫做 轮询,这会尽可能地占用很多CPU资源。

如果你使用线程的话,就不需要进行轮询了。只要去掉 setblocking(0) 这一行,程序就应该能正常工作。

撰写回答