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.进程(最小的资源单位): 进程:就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成. 程序:我们编写的程序用来描述进程要完成哪些功能以 ...
随机推荐
- 【Java----创建多级文件夹】
File类中的mkdir()和mkdirs(): mkdir():只能创建一层目录. mkdirs():可以创建多层目录 代码:path可以是带文件名称的全路径 //路径 String path = ...
- 【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑
题意 给出一张无向图,求出恰巧经过n条边的最短路. 题解 考虑先离散化,那么点的个数只会有202个最多.于是复杂度里面就可以有一个\(n^3\).考虑构造矩阵\(d^1\)表示经过一条边的最短路,那么 ...
- 使用PlaceHolder,测试碰见的问题
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFa ...
- RabbitMQ学习之延时队列
原帖参考:http://www.cnblogs.com/telwanggs/p/7124687.html?utm_source=itdadao&utm_medium=referral http ...
- 主键非自增列 EF 插入数据库引起的 ID 列不能为 NULL 的错误
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<PostBo ...
- React生命周期执行顺序详解
文章内容转载于https://www.cnblogs.com/faith3/p/9216165.html 一.组件生命周期的执行次数是什么样子的??? 只执行一次: constructor.compo ...
- idea环境下建立maven工程并运行scala程序
idea中scala编程环境及建立maven工程 1.下载idea软件并破解:http://blog.csdn.net/nn_jbrs/article/details/70139178 2.安装sca ...
- 力扣(LeetCode) 1010. 总持续时间可被 60 整除的歌曲
在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒. 返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量.形式上,我们希望索引的数字 i < j 且有 (time[i] + ...
- 力扣 报错 runtime error: load of null pointer of type 'const int'
runtime error: load of null pointer of type 'const int' 要求返回的是int* 解决方案 1.指针使用malloc分配空间 用 int * p = ...
- leecode第七十八题(子集)
class Solution { public: vector<vector<int>> subsets(vector<int>& nums) { vect ...