目录
概念介绍
测试环境
开始测试
测试【单进程单线程】
测试【多进程 并行】
测试【多线程 并发】
测试【协程 + 异步】
结果对比
绘图展示
概念介绍
首先简单介绍几个概念:

进程和线程
进程就是一个程序在一个数据集上的一次动态执行过程(数据集是程序在执行过程中所需要使用的资源)。
线程也叫轻量级进程,它是一个基本的 CPU 执行单元,是比进程更小的能独立运行的基本单位。
进程和线程的关系:
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
资源分配给进程,同一进程的所有线程共享该进程的所有资源。
CPU 分给线程,即真正在 CPU 上运行的是线程。
并行和并发
并行处理是计算机系统中能同时执行两个或更多个处理的一种计算方法。并行处理可同时工作于同一程序的不同方面,其主要目的是节省大型和复杂问题的解决时间。
并发处理指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个 CPU 上运行,但任一个时刻点上只有一个程序在 CPU 上运行。
并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以说,并行是并发的子集。多进程是并行的,多线程是并发的。
同步和异步
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
举个例子,打电话时就是同步通信,发短息时就是异步通信。
测试环境
进行对比测试之前,我们先来创建一个合适的实验环境:
       模拟一个需要等待一定时间才可以获取返回结果的网页。
如果直接用百度、CSDN 等站点的话,一方面响应太快、难以看出各种方法的差距,另一方面响应速度会受网速影响、每次发送请求获取响应所需的时间不完全一致导致重复实验结果差距较大,所以在此用 Flask 模拟一个本地慢速服务器。
flask_server.py 代码如下:

from flask import Flask # pip install flask
import time

app = Flask(__name__)

@app.route('/')
def index():
time.sleep(3) # 休眠 3 秒再返回结果
return 'Hello!'

if __name__ == '__main__':
app.run(threaded=True) # 以多线程模式启动服务

启动之后,Flask 服务默认在 127.0.0.1:5000 上运行,控制台输出结果如下:

* Serving Flask app "flask_server" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

在浏览器中访问 http://127.0.0.1:5000/ 等待 3 秒即会出现 Hello! 页面,表明简单的慢速服务器搭建完成!

开始测试
首先导入需要的模块,以请求 10 次为例准备 urls,再定义一个 get_html_text() 函数:

import requests
import time
# 用于多进程
from multiprocessing import Process
# 用于多线程
from threading import Thread
# 用于协程+异步
import asyncio
import aiohttp # pip install aiohttp

urls = ['http://127.0.0.1:5000' for _ in range(10)]

def get_html_text(url):
response = requests.get(url)
return response.text

测试【单进程单线程】
start = time.time()
for url in urls:
result = get_html_text(url)
print(result)
end = time.time()
print('【单进程单线程】耗时:%s 秒' %(end - start))

结果如下:

Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
【单进程单线程】耗时:30.15605854988098 秒

测试【多进程 并行】
start = time.time()
processes = []
for url in urls:
p = Process(target=get_html_text, args=(url,))
processes.append(p)
p.start()
for p in processes:
p.join()
print('Hello!')
end = time.time()
print('【多进程 并行】耗时:%s 秒' %(end - start))

结果如下(测试电脑为 4 核 CPU,核心数越大加速越明显):

Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
【多进程 并行】耗时:5.511234283447266 秒

测试【多线程 并发】
start = time.time()
threads = []
for url in urls:
t = Thread(target=get_html_text, args=(url,))
threads.append(t)
t.start()
for t in threads:
t.join()
print('Hello!')
end = time.time()
print('【多线程 并发】耗时:%s 秒' %(end - start))

结果如下:

Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
【多线程 并发】耗时:3.030653953552246 秒

测试【协程 + 异步】
# 因为 requests 模块不支持异步操作,需要借助 aiohttp 模块
async def get_html_text_async(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
text = await response.text()
return text

start = time.time()
tasks = [asyncio.ensure_future(get_html_text_async(url)) for url in urls]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
for task in tasks:
print(task.result())
end = time.time()
print('【协程 ++ 异步】耗时:%s 秒' %(end - start))

结果如下:

Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
【协程 ++ 异步】耗时:3.046288251876831 秒

结果对比
len(urls)==1:

单进程单线程3。0078秒

多进程 并发 3.83秒

多线程并发3.0073秒

携程+异步3.0133

len(urls)==4:

单进程单线程12秒

多进程 并发 4秒

多线程并发3.01秒

携程+异步3.02秒

len(urls)==10:

单进程单线程30.1秒

多进程 并发 5.5秒

多线程并发3.030秒

携程+异步3.046秒

len(urls)==100:

单进程单线程301.10秒

多进程 并发 23.81秒

多线程并发3.15秒

携程+异步3.19秒

python对比线程,进程,携程,异步,哪个快的更多相关文章

  1. python中线程 进程 协程

    多线程:#线程的并发是利用cpu上下文的切换(是并发,不是并行)#多线程执行的顺序是无序的#多线程共享全局变量#线程是继承在进程里的,没有进程就没有线程#GIL全局解释器锁#只要在进行耗时的IO操作的 ...

  2. 进程、线程和携程的通俗解释【刘新宇Python】

    通过下面这张图你就能看清楚了,进程.线程和携程的关系   进程: 多个进程是可以运行在多个CPU当中的,比如你的电脑是4核,可以同时并行运行四个进程,这是真正物理上的并行运行. 线程: 每个进程又可以 ...

  3. 学到了林海峰,武沛齐讲的Day34 完 线程 进程 协程 很重要

    线程 进程 协程 很重要 ...儿子满月回家办酒,学的有点慢,坚持

  4. Python学习笔记整理总结【网络编程】【线程/进程/协程/IO多路模型/select/poll/epoll/selector】

    一.socket(单链接) 1.socket:应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socke ...

  5. 11.python之线程,协程,进程,

    一,进程与线程 1.什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行 ...

  6. 12.python进程\协程\异步IO

    进程 创建进程 from multiprocessing import Process import time def func(name): time.sleep(2) print('hello', ...

  7. 15.python并发编程(线程--进程--协程)

    一.进程:1.定义:进程最小的资源单位,本质就是一个程序在一个数据集上的一次动态执行(运行)的过程2.组成:进程一般由程序,数据集,进程控制三部分组成:(1)程序:用来描述进程要完成哪些功能以及如何完 ...

  8. python 线程 进程 协程 学习

    转载自大神博客:http://www.cnblogs.com/aylin/p/5601969.html 仅供学习使用···· python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和 ...

  9. python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...

随机推荐

  1. PyTorch中使用深度学习(CNN和LSTM)的自动图像标题

    介绍 深度学习现在是一个非常猖獗的领域 - 有如此多的应用程序日复一日地出现.深入了解深度学习的最佳方法是亲自动手.尽可能多地参与项目,并尝试自己完成.这将帮助您更深入地掌握主题,并帮助您成为更好的深 ...

  2. Go项目的测试代码2(项目运用)

    上一篇文章介绍了最基本的测试代码的写法.Go项目的测试代码(基础) 这里简单的共享一下我在项目中使用的方式. 项目结构 我们实际项目中, 结构简单地分了控制层controllers和模块层models ...

  3. nginx详解(代理服务器的解释+nginx 在linux 下的安装+nginx.conf 中的配置解释)

    一.概论 1.什么是代理服务器 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬 ...

  4. 小D课堂 - 新版本微服务springcloud+Docker教程_5-01分布式核心知识之熔断、降级

    笔记: 第五章 互联网架构服务降级熔断 Hystrix 实战 1.分布式核心知识之熔断.降级讲解     简介:系统负载过高,突发流量或者网络等各种异常情况介绍,常用的解决方案 1.熔断:       ...

  5. presto安装

    下载 presto-server-0.217 包 进入presto根目录,新建脚本deploy.sh mkdir etc cd etc #配置 cat >config.properties &l ...

  6. SSIS数据同步实践

    SSIS数据同步实践   背景 在已初步验证不同实例下同构表数据同步方案之后,为了实现数据持续同步,需使用SSIS把之前的生成脚本和执行脚本的两个步骤组合在一起部署成包之后,通过JOB定时去执行: 测 ...

  7. Linux - curl和Wget

    curl - transfer a URL curl SYNOPSIS curl [options] [URL...] DESCRIPTION curl is a tool to transfer d ...

  8. 【笔记】7天玩转容器&CKA管理员实训

    第一部分 day1,容器基础知识介绍 安装 apt-get install docker-engine [root@cce-7day-fudonghai-24106 01CNL]# docker -v ...

  9. postman生成格式化时间

    方法一: var moment = require('moment'); var data = moment().format(" YYYYMMDDHHmmss"); consol ...

  10. Django 1.x版本与2.x版本 区别

    django 1.x版本与2.x版本 URL区别 在django 1.x中的方式 导入的模块是'from django.conf.urls import url',urlpatterns中url对应的 ...