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

进程和线程
进程就是一个程序在一个数据集上的一次动态执行过程(数据集是程序在执行过程中所需要使用的资源)。
线程也叫轻量级进程,它是一个基本的 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. Flutter移动电商实战 --(5)dio基础_引入和简单的Get请求

    这篇开始我们学习Dart第三方Http请求库dio,这是国人开源的一个项目,也是国内用的最广泛的Dart Http请求库. 1.dio介绍和引入 dio是一个强大的Dart Http请求库,支持Res ...

  2. [log4j]Error:The method getLogger(String) in the type Logger is not applicable for the arguments

    原因:本该导入import org.apache.log4j.Logger; 结果成了import java.util.logging.Logger; 如果硬把private static Logge ...

  3. javascript对象属性和数组的访问

    javascript对象属性的访问 假如有对象test:var test = {  "a":1,  "b":2};直接访问对象test的属性a的值,有两种方法: ...

  4. 如何快速查找到HTML头尾对应标签?

    在使用Atom编辑器整理HTML代码的时候,希望快速找到HTML头尾对应的标签.  ctrl+m 试试看 

  5. 三分钟读懂TT猫分布式、微服务和集群之路 (转)

    http://www.cnblogs.com/smallSevens/p/7501932.html 针对新手入门的普及,有过大型网站技术架构牛人路过,别耽误浪费了时间,阅读之前,请确保有一定的网络基础 ...

  6. python中学习K-Means和图片压缩

    python中学习K-Means和图片压缩 大家在学习python中,经常会使用到K-Means和图片压缩的,我们在此给大家分享一下K-Means和图片压缩的方法和原理,喜欢的朋友收藏一下吧. 通俗的 ...

  7. excel怎么设置密码保护?Excel文件添加密码保护教程

    excel怎么设置密码保护?Excel文件添加密码保护教程 众所周知,Excel具有强大的数据处理和数据分析能力,广泛应用于加工学统计及金融统计中.特别是金融统计需要较高的安全性,那么就一定要为Exc ...

  8. 安装cni网络插件-非必须

    安装cni网络插件 安装cni # 安装 cni # 百度云链接:https://pan.baidu.com/s/1-PputObLs5jouXLnuBCI6Q 密码:tzqm cd /server/ ...

  9. Spring Boot开发Web应用之JSP篇

    前言 上一篇介绍了Spring Boot中使用Thymeleaf模板引擎,今天来介绍一下如何使用SpringBoot官方不推荐的jsp,虽然难度有点大,但是玩起来还是蛮有意思的. 正文 先来看看整体的 ...

  10. 【计算机视觉】【并行计算与CUDA开发】OpenCV中GPU模块使用

    CUDA基本使用方法 在介绍OpenCV中GPU模块使用之前,先回顾下CUDA的一般使用方法,其基本步骤如下: 1.主机代码执行:2.传输数据到GPU:3.确定grid,block大小: 4.调用内核 ...