为什么 Python 网络请求使用线程池反而更慢了

我在一台树莓派(当服务器,即服务端角色)上开起了一个 Nginx 服务

sudo apt install nginx
─➤  sudo service nginx status  

● nginx.service - A high performance web server and a reverse proxy server

Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)

Active: active (running) since Mon 2022-01-03 03:46:08 UTC; 12min ago

Docs: man:nginx(8)

Main PID: 138419 (nginx)

Tasks: 5 (limit: 4435)

CGroup: /system.slice/nginx.service

├─138419 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;

├─138420 nginx: worker process

├─138421 nginx: worker process

├─138422 nginx: worker process

└─138423 nginx: worker process

Jan 03 03:46:08 RaspberryPi systemd[1]: Starting A high performance web server and a reverse proxy server...

Jan 03 03:46:08 RaspberryPi systemd[1]: Started A high performance web server and a reverse proxy server.

在另一台机器上请求服务端 Nginx,代码如下:

下面就是客户端的代码

from concurrent.futures import ThreadPoolExecutor

import requests

def func():

requests.get('http://192.168.31.203')

pool = ThreadPoolExecutor(max_workers=10)

for i in range(3000):

pool.submit(func)

max_workers 表示线程池中线程数量的上限

当 max_workers = 1 的时候,耗时:5 秒:

─➤  time python test_threading_pool.py

python test_threading_pool.py 3.85s user 0.25s system 70% cpu 5.814 total

max_workers = 10 的时候,耗时:10 秒:

➤  time python test_threading_pool.py

python test_threading_pool.py 10.77s user 0.98s system 114% cpu 10.273 total

非常差异的是,反而变慢了!

网络拓扑图

为什么 Python 网络请求使用线程池反而更慢了

客户端情况描述

客户端使用的 python 版本

为什么 Python 网络请求使用线程池反而更慢了

客户端机器的硬件配置:
操作系统:Ubuntu20.04
cpu:AMD 5700G 8核心16线程
内存:32GB DDR4 3200MHZ
网卡:intel AX200

为什么 Python 网络请求使用线程池反而更慢了

服务端配置描述

硬件配置:

树莓派4B 配置
操作系统:Ubuntu20.04
cpu:博通 BCM2711,1.5 GHz 64 位 4 核心 Cortex-A72(ARM v8)
内存:4 GB RAM
网卡:千兆以太网

为什么 Python 网络请求使用线程池反而更慢了


为什么?

即便算上创建线程池和对应线程的开销和线程切换的开销,也不至于这么慢吧!

每次上下文切换需要几十纳秒到数微秒之间。 这个时间还是相当客观的,在高并发场景中,进程下上文切换次数较多,很容易出现大量CPU时间浪费在寄存器,内核栈以及虚拟内存等资源的保存以及恢复上,从而大大减少了进程运行的实际时间。这也是导致系统平均负载升高的原因之一。

参考资料:
CPU 上下文切换
提问的智慧


回答:

主要问题是被请求方(http://192.168.31.203)不支持并发,1个请求与10个请求一起过来对它可能都是串行执行,10个过来反而多占用它的资源,所以不是开了并发就快 也要看对方行不行


回答:

就是因为你的例子太极端了。

ngingx返回简单 + 网络为本地 ,这两者导致请求的整个流程几乎都是cpu密集型 ,多线程的优势没有提现出来。

这个时候的线程数跟你本机的核心数有个最优值,只有在那个最优值才能得到最短时间

以上是 为什么 Python 网络请求使用线程池反而更慢了 的全部内容, 来源链接: utcz.com/p/938294.html

回到顶部