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中单线程、多线程和多进程的效率对比实验的更多相关文章

  1. 011_Python中单线程、多线程和多进程的效率对比实验

    Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread)的情况下,不能发挥多核的优势.而使用多进程(Multiprocess),则可以发挥多 ...

  2. 在python中单线程,多线程,多进程对CPU的利用率实测以及GIL原理分析

    首先关于在python中单线程,多线程,多进程对cpu的利用率实测如下: 单线程,多线程,多进程测试代码使用死循环. 1)单线程: 2)多线程: 3)多进程: 查看cpu使用效率: 开始观察分别执行时 ...

  3. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  4. python爬虫之多线程、多进程+代码示例

    python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 一.什么是进程和线程 引用廖雪峰的官方网站关于进程和线程的讲解: 进程:对于操作系统来说,一个任 ...

  5. python分别使用多线程和多进程获取所有股票实时数据

    python分别使用多线程和多进程获取所有股票实时数据   前一天简单介绍了python怎样获取历史数据和实时分笔数据,那么如果要获取所有上市公司的实时分笔数据,应该怎么做呢? 肯定有人想的是,用一个 ...

  6. python中的多线程和多进程

    一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...

  7. java中多种写文件方式的效率对比实验

    一.实验背景 最近在考虑一个问题:“如果快速地向文件中写入数据”,java提供了多种文件写入的方式,效率上各有异同,基本上可以分为如下三大类:字节流输出.字符流输出.内存文件映射输出.前两种又可以分为 ...

  8. Python进阶:多线程、多进程和线程池编程/协程和异步io/asyncio并发编程

    gil: gil使得同一个时刻只有一个线程在一个CPU上执行字节码,无法将多个线程映射到多个CPU上执行 gil会根据执行的字节码行数以及时间片释放gil,gil在遇到io的操作时候主动释放 thre ...

  9. python之路-----多线程与多进程

    一.进程和线程的概念 1.进程(最小的资源单位): 进程:就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成. 程序:我们编写的程序用来描述进程要完成哪些功能以 ...

随机推荐

  1. oracle 之 连接查询

    where 连接 select * from a,b //使用的是笛卡尔乘积  显示 a.count*b.count 条数 select * from a,b where a.id=b.id 其实只是 ...

  2. 深度学习课程笔记(十一)初探 Capsule Network

    深度学习课程笔记(十一)初探 Capsule Network  2018-02-01  15:58:52 一.先列出几个不错的 reference: 1. https://medium.com/ai% ...

  3. (zhuan) LSTM Neural Network for Time Series Prediction

    LSTM Neural Network for Time Series Prediction Wed 21st Dec 2016 Neural Networks these days are the ...

  4. x=x+1,x+=1,及x++的效率哪个最高,为什么?

    x=x+1: 1.     读取右X的地址 2.     X+1 3.     读取左X的地址 4.     将右值传给左边的X x+=1: 1.     读取右边的x的地址 2.     X+1 3 ...

  5. Levenshtein Distance,判断字符串的相似性

    private int LevenshteinDistance(string s1,string s2,int maxValue) { if (s1 == null|| s1.Length == 0) ...

  6. MySQL获取指定长度的字符串的函数left(s,n)和right(s,n)

    1.LEFT(s,n)函数返回字符串s开始的最左边n个字符. eg: select left(‘abcde12345‘,5);   ======>‘abcde‘ 2.RIGHT(s,n)函数返回 ...

  7. jdk1.8和tomcat9.0、maven3.5.0配置教程

    一.jdk环境变量 JAVA_HOME :C:\Program Files\Java\jdk1.8.0_77(这个是你安装JDK时的路径,按照实际情况改成你自己的目录) CLASSPATH:   .; ...

  8. C#在高分屏上让窗体程序忽略系统的显示缩放

    [STAThread] static void Main() { ) SetProcessDPIAware(); Application.EnableVisualStyles(); Applicati ...

  9. Python 学习笔记 多进程 multiprocessing--转载

    本文链接地址 http://quqiuzhu.com/2016/python-multiprocessing/ Python 解释器有一个全局解释器锁(PIL),导致每个 Python 进程中最多同时 ...

  10. 力扣(LeetCode)1009. 十进制整数的反码

    每个非负整数 N 都有其二进制表示.例如, 5 可以被表示为二进制 "101",11 可以用二进制 "1011" 表示,依此类推.注意,除 N = 0 外,任何 ...