【问题标题】:Python server program has high cpu usagePython服务器程序cpu使用率高
【发布时间】:2014-07-13 07:42:06
【问题描述】:

我正在试验一个 python tcp 服务器(我最近才发现了 python 的厉害之处)。无论如何,服务器运行得很好,并以我期望的方式打印数据,但是当我在 windows 任务管理器中查看 CPU 使用率时,它显示 python.exe 正在消耗 97%-99% 的 CPU。

为了看看会发生什么,我在另一台计算机上再次运行它,它只使用了大约 50% 的 cpu。

这是我想知道的:

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

  2. 为什么我会在两台不同的机器上看到差异(一台是 Windows 7,另一台是 server 2008,这有关系吗)?

  3. 我正在为每个连接创建一个新线程,并运行一个始终正确的 while 循环,但是当不再有连接时我有一个“中断”。这个线程被正确销毁了吗?

提前感谢您的帮助!

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

【问题讨论】:

  • 您应该在代码审查中发布此内容,因为它似乎是功能代码。
  • 我不知道代码审查。那我应该删除这个帖子吗?
  • 我不是 100% 确定,可能想问元聊天
  • 我确信 Win 7 机器和服务器上的硬件属性会有所不同。这就是为什么他们有不同的表现!
  • 我在 Windows 8 64 位、核心 i5 6GB 内存上测试了您的代码,在我的情况下 CPU 使用率从未超过 32%!

标签: python multithreading tcp


【解决方案1】:

您正在使用setblocking(0),这意味着您的套接字没有阻塞。你正在做的事情叫做polling,并且会使用尽可能多的CPU。

当您使用线程时,您不需要轮询。只需删除 setblocking(0) 行,它应该可以正常工作。

【讨论】:

  • 你是对的。太感谢了! cpu 使用率现在可以忽略不计了。
【解决方案2】:

问题是无限的while循环(while 1)。请包含几微秒的延迟(time.sleep(0.001)),这会大幅降低 CPU 使用率。

【讨论】:

    【解决方案3】:

    只对 rsy 的回答发表评论以降低声誉。 在您的特定情况下,当您使用“conn.recv”接收数据时,只需设置 setblocking(1) 即可解决问题,正如 pmoleri 已回答的那样。

    但是,如果您使用“select”语句在循环中进行轮询,那么 setblocking(1) 没有任何效果,并且 rsy 的解决方案具有短暂的延迟 (time.delay(0.01))。

    【讨论】:

      猜你喜欢
      • 2015-08-05
      • 1970-01-01
      • 2020-09-30
      • 2018-07-08
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多