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

进程和线程
进程就是一个程序在一个数据集上的一次动态执行过程(数据集是程序在执行过程中所需要使用的资源)。
线程也叫轻量级进程,它是一个基本的 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. linux 搜索文件夹下的所有文件内容

    find . -type f -name "*.*" | xargs grep "博客园"

  2. [MySql]MySql中外键设置 以及Java/MyBatis程序对存在外键关联无法删除的规避

    在MySql设定两张表,其中product表的主键设定成orderTb表的外键,具体如下: 产品表: create table product(id INT(11) PRIMARY KEY,name ...

  3. SpringCloud(七)之SpringCloud的链路追踪组件Sleuth实战,以及 zipkin 的部署和使用

    一.前言 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案 ,并且兼容了zipkin,提供了REST API接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序 . ...

  4. ShockUtil振动工具类

    import android.app.Activity; import android.app.Service; import android.content.Context; import andr ...

  5. [Mysql]一对多关系是如何发挥作用的?

    一个孩子只有一个妈妈,而一个妈妈可以有多个孩子,这是典型的一对多的关系,这里采用navicat图形化界面建立二者的关系. 第一步:创建mother表,如下图:  第二步:创建children表,在ch ...

  6. vlc命令行: 转码 流化 推流

    vlc命令行: 转码 流化 推流 写在命令行之前的话: VLC不仅仅可以通过界面进行播放,转码,流化,也可以通过命令行进行播放,转码和流化.还可以利用里面的SDK进行二次开发. vlc命令行使用方法: ...

  7. robotframework 接口测试 +RSA 加密

    首先,实现RSA加密,需要用到pycrypto这个库,这个库又依赖openssl,所以需要先下载openssl,具体教程可以参考http://bbs.csdn.net/topics/392193545 ...

  8. 【Hadoop】MapReduce练习:分科目等级并按分区统计学生以及人数

    需求 ​ 背景:学校的学生的是一个非常大的生成数据的集体,比如每次考试的成绩 ​ 现有一个班级的学生一个月的考试成绩数据. ​ 科目 姓名 分数 ​ 需求:求出每门成绩中属于甲级的学生人数和总人数 ​ ...

  9. Etherscan

    转载声明:https://blog.csdn.net/shebao3333/article/details/79858250 (仅方便自己查看及原文章被删除) 什么是Etherscan? 简单来说是一 ...

  10. Linux服务器上安装openoffice,以及安装字体文件

    1.安装openoffice (1)将openoffice的linux安装包放到linux指定的文件下(一般放在opt下) (2)在安装包的目录下执行命令:tar -zxvf 对应的压缩包名字 (3) ...