Python中单线程、多线程和多进程的效率对比实验
GIL机制导致如下结果:
Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)
python多线程适合io操作密集型的任务(如socket server 网络并发这一类的);
python多线程不适合cpu密集操作型的任务,主要使用cpu来计算,如大量的数学计算。
那么如果有cpu密集型的任务怎么办,可以通过多进程来操作(不是多线程)。
假如CPU有8核,每核CPU都可以用1个进程,每个进程可以用1个线程来进行计算。
1、线性模式测试
import requests
import time
from threading import Thread
from multiprocessing import Process #定义CPU密集的计算函数
def count(x, y):
# 使程序完成150万计算
c = 0
while c < 500000:
c += 1
x += x
y += y #定义IO密集的文件读写函数
def write():
f = open("test.txt", "w")
for x in range(5000000):
f.write("testwrite\n")
f.close() def read():
f = open("test.txt", "r")
lines = f.readlines()
f.close() def io():
write()
read() #定义网络请求函数
_head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'}
url = "http://www.tieba.com"
def http_request():
try:
webPage = requests.get(url, headers=_head)
html = webPage.text
return {"context": html}
except Exception as e:
return {"error": e} #---------------------------------------
#CPU密集操作
t = time.time()
for x in range(10):
count(1, 1)
print("Line cpu", time.time() - t) # IO密集操作
t = time.time()
for x in range(10):
io()
print("Line IO", time.time() - t) # 网络请求密集型操作
t = time.time()
for x in range(10):
http_request()
print("Line Http Request", time.time() - t)
--运行---------------------结果:
('Line cpu', 97.26900005340576)
('Line IO', 24.319000005722046)
('Line Http Request', 209.94899988174438)
2、线程模式测试
#定于线程公共函数
def mythread(fun,*args):
counts = []
for x in range(10):
thread = Thread(target=fun, args=args)
counts.append(thread)
thread.start()
e = counts.__len__()
while True:
for th in counts:
if not th.is_alive():
e -= 1
if e <= 0:
break #测试多线程并发执行CPU密集操作所需时间
t = time.time()
mythread(count,1,1)
print("thread cpu ",time.time() - t) #测试多线程并发执行IO密集操作所需时间
t = time.time()
mythread(io)
print("thread IO ",time.time() - t) #测试多线程并发执行网络密集操作所需时间
t = time.time()
mythread(http_request)
print("Thread Http Request", time.time() - t)
--运行---------------------结果:
('thread cpu ', 102.20300006866455)
('thread IO ', 654.5730001926422)
('Thread Http Request', 21.170999765396118)
3.进程模式测试
def myprocess(fun,*args):
counts = []
for x in range(10):
process = Process(target=fun,args=args)
counts.append(process)
process.start()
e = counts.__len__()
while True:
for th in counts:
if not th.is_alive():
e -= 1
if e <= 0:
break if __name__ == '__main__': #没这句会报错。
#测试多进程并发执行CPU密集操作所需时间
t = time.time()
myprocess(count,1,1)
print("Multiprocess cpu", time.time() - t) #测试多进程并发执行IO密集型操作
t = time.time()
myprocess(io)
print("Multiprocess IO", time.time() - t) #测试多进程并发执行Http请求密集型操作
t = time.time()
myprocess(http_request)
print("Multiprocess Http Request", time.time() - t)
--运行---------------------结果:
('Multiprocess cpu', 20.168999910354614)
('Multiprocess IO', 11.82699990272522)
('Multiprocess Http Request', 21.805000066757202)
实验结果
| CPU密集型操作 | IO密集型操作 | 网络请求密集型操作 | |
| 单线程操作 | 97 | 24 | 310 |
| 多线程操作 | 102 | 654 | |
| 多进程操作 | 22 |
通过上面的结果,我们可以看到:
- 多线程在IO密集型的操作下似乎也没有很大的优势,在CPU密集型的操作下明显地比单线程线性执行性能更差,但是对于网络请求这种忙等阻塞线程的操作,多线程的优势便非常显著了
- 多进程无论是在CPU密集型还是IO密集型以及网络请求密集型(经常发生线程阻塞的操作)中,都能体现出性能的优势。不过在类似网络请求密集型的操作上,与多线程相差无几,但却更占用CPU等资源,所以对于这种情况下,我们可以选择多线程来执行
一句话总结:cpu和io密集操作使用多进程,网络操作使用多线程
Python中单线程、多线程和多进程的效率对比实验的更多相关文章
- 011_Python中单线程、多线程和多进程的效率对比实验
Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread)的情况下,不能发挥多核的优势.而使用多进程(Multiprocess),则可以发挥多 ...
- 在python中单线程,多线程,多进程对CPU的利用率实测以及GIL原理分析
首先关于在python中单线程,多线程,多进程对cpu的利用率实测如下: 单线程,多线程,多进程测试代码使用死循环. 1)单线程: 2)多线程: 3)多进程: 查看cpu使用效率: 开始观察分别执行时 ...
- 第十章:Python高级编程-多线程、多进程和线程池编程
第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...
- python爬虫之多线程、多进程+代码示例
python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 一.什么是进程和线程 引用廖雪峰的官方网站关于进程和线程的讲解: 进程:对于操作系统来说,一个任 ...
- python分别使用多线程和多进程获取所有股票实时数据
python分别使用多线程和多进程获取所有股票实时数据 前一天简单介绍了python怎样获取历史数据和实时分笔数据,那么如果要获取所有上市公司的实时分笔数据,应该怎么做呢? 肯定有人想的是,用一个 ...
- python中的多线程和多进程
一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...
- java中多种写文件方式的效率对比实验
一.实验背景 最近在考虑一个问题:“如果快速地向文件中写入数据”,java提供了多种文件写入的方式,效率上各有异同,基本上可以分为如下三大类:字节流输出.字符流输出.内存文件映射输出.前两种又可以分为 ...
- Python进阶:多线程、多进程和线程池编程/协程和异步io/asyncio并发编程
gil: gil使得同一个时刻只有一个线程在一个CPU上执行字节码,无法将多个线程映射到多个CPU上执行 gil会根据执行的字节码行数以及时间片释放gil,gil在遇到io的操作时候主动释放 thre ...
- python之路-----多线程与多进程
一.进程和线程的概念 1.进程(最小的资源单位): 进程:就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成. 程序:我们编写的程序用来描述进程要完成哪些功能以 ...
随机推荐
- Tutorial on GoogleNet based image classification --- focus on Inception module and save/load models
Tutorial on GoogleNet based image classification 2018-06-26 15:50:29 本文旨在通过案例来学习 GoogleNet 及其 Incep ...
- [蓝桥] 算法训练 K好数
时间限制:1.0s 内存限制:256.0MB 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = ...
- computed 计算选项
computed 的作用主要是对原数据进行改造输出.改造输出:包括格式的编辑,大小写转换,顺序重排,添加符号……. 格式化输出结果 我们先来做个读出价格的例子:我们读书的原始数据是price:100 ...
- Vue.set全局操作
Vue.set 的作用就是在构造器外部操作构造器内部的数据.属性或者方法.比如在vue构造器内部定义了一个count为1的数据,我们在构造器外部定义了一个方法,要每次点击按钮给值加1.就需要用到Vue ...
- MongoDB集群配置笔记一
MongoDB 的部署方案有单机部署.复本集(主备)部署.分片部署.复本集与分片混合部署.混合的部署方式如图: 分片集群的构造 (1)mongos :数据路由,和客户端打交道的模块.mongos本身没 ...
- Latex: 减少图与文字之间的空白间隙
参考: Remove space after figure and before text Latex: 减少图与文字之间的空白间隙 论文中图与文字之间的空白间隙过大,导致排版不大美观.解决方法是在\ ...
- algorithm.sty not found error in LaTeX 解决方法
参考: algorithm.sty not found error in LaTeX algorithm.sty not found error in LaTeX 解决方法 错误日志: LaTeX E ...
- appium长按按钮
public static AndroidDriver driver; /长按操作:waitAction的参数单位是ms/ public static void longClick(String id ...
- JS实现ul,li排序效果
<!DOCTYPE html> <html> <head> <title>js列表排序</title> <meta charset=& ...
- Android 4.0之后的日历控件拥挤的解决办法
本意是想做成这个样子的控件: 发现使用datepicker之后,效果完全不同,把整个日历都显示出来了.非常拥挤. 在datepicker中加入android:calendarViewShown=&qu ...