进程and线程and协程效率对比
1.进程与进程池的效率对比
- 多进程:p.start()过程中,只是向操作系统发送一个信号,至于什么时候执行,都是操作系统的事情,操作系统接收到信号时,帮该进程申请一块内存空间+拷贝父进程的地址空间
#多进程执行效率
from multiprocessing import Process
import time
def func(i):
sum = 0
time.sleep(1)
sum += i
print(sum) if __name__ == '__main__':
ls = []
statt = time.time()
for i in range(10):
p = Process(target=func,args=((i,)))
p.start()
ls.append(p)
[p.join() for p in ls]
print(time.time() - statt) #执行时间
1.3582112789154053
多进程的执行
- 进程池:
一个池子,里边有固定数量的进程。这些进程一直处于待命状态,一旦有任务来,马上就有进程去处理。
因为在实际业务中,任务量是有多有少的,如果任务量特别的多,不可能要开对应那么多的进程数
开启那么多进程首先就需要消耗大量的时间让操作系统来为你管理它。其次还需要消耗大量时间让
cpu帮你调度它。
进程池还会帮程序员去管理池中的进程。
#进程池的效率
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process
import time
def func(i):
sum = 0
time.sleep(1)
sum += i
return sum
ls = []
if __name__ == '__main__':
p = ProcessPoolExecutor(4)
start = time.time() for i in range(10): #向进程池中丢任务,这十个发送的信号会被直接添加到列表中
#至于你执行不执行,那是操作系统的事,这时列表中就有了十个返回值对象
obj = p.submit(func,i)
ls.append(obj) #任务对象会在ls列表中依次排好顺序,然后p.result()会依次等待结果!
[print(p.result()) for p in ls]
print(time.time() - start) #上面列表等待的话,这里会一瞬间完成,因为上面代码中每个任务都已经执行结束
p.shutdown(wait=True)
#时间效率
3.124636650085449
进程池的时间效率
- 总结:
如果在机器可承受范围内,进程数开的越多,执行效率越快!
1.轻量级的任务多进程和进程池的执行效率相差不大;因为在开多进程时,开启进程的时间
和cpu切换的时间可以忽略不计!
2.任务量较大时,因为进程池里已经有开启好的进程,随时可以调度,节省了多进程开启进程的时间
和资源利用率!
2.线程与进程对比
- 线程:线程被称为轻量级的进程,好比一个车间的一条流水线,是可执行的基本单位,是可被调度的基本单位,线程不可以自己独立拥有资源,只有开启进程了,才有线程的概念,必须依赖于所属进程中的资源;所以线程中没有父子关系,因为大家用的都是进程的资源,都是进程创建出来的;
- 进程:是一个执行过程,是一个资源分配的基本单位,进程与进程之间是独立的,主进程与子进程之间是相互隔离的,每一个进程默认都有一个控制线程,该线程可以执行代码,从而创建新的线程;
- 线程分为用户级线程和内核级线程:
- 用户级线程:对于程序员来说的,这样的线程完全被程序员控制执行,调度
- 内核级线程:对于计算机内核来说,这样的线程完全被内核控制调度
- 进程由 代码段 数据段 PCB组成(process control block)
- 线程由 代码段 数据段 TCB组成(thread control block)
- 线程分为用户级线程和内核级线程:
n = 100
def func():
global n
n = 0
if __name__ == '__main__':
p = Thread(target=func,)
p.start()
print('线程的n值:%s'% n)
#线程的n值:0
所以线程是共用了进程的资源,
线程的特点
n = 100
def func():
global n
n = 0
if __name__ == '__main__':
p = Process(target=func,)
p.start()
print('线程的n值:%s'% n)
#输出结果
线程的n值:100
进程是相互空间隔离的
进程的特点
3.线程与线程池
- 回调函数:线程池的回调函数是由主进程调用的,子进程只负责把结果传递给回调函数,回调函数通过result()取得对象,再进行进一步的操作;
- 线程的回调函数是子线程调用,而不是主线程;
- 线程池跟进程池的概念一样,它的开启都不是无限的,默认也是内核乘以5;
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import requests
from threading import current_thread
def func(url):
respons = requests.get(url)
if respons.status_code == 200:
return {'url':url,'text':respons.text}
def call_back(obj):
#回调函数:
#1.在主线程中可以等你运行完了,统一对线程result取得结果
#2.但是你还得等待每一个线程运行结束,而回调函数,是每一个线程附带一个函数,一旦运行结束
#就将对象传给回调函数,回调函数result()取得子线程的返回值
res = obj.result()
print('[%s] <%s> (%s)' % (current_thread().getName(), res['url'], len(res['text']))) if __name__ == '__main__':
url = [
'https://www.bilibili.com',
'https://www.baidu.com',
'https://www.tmall.com',
'https://www.jd.com'
]
p = ThreadPoolExecutor(5)
for i in url:
p.submit(func,i).add_done_callback(call_back)
p.shutdown(wait=True)
#输出结果
[ThreadPoolExecutor-0_1] <https://www.baidu.com> (2443)
[ThreadPoolExecutor-0_0] <https://www.bilibili.com> (28253)
[ThreadPoolExecutor-0_2] <https://www.tmall.com> (216218)
[ThreadPoolExecutor-0_3] <https://www.jd.com> (107838)
利用回调函数的爬虫
4.协程与IO多路复用
进程and线程and协程效率对比的更多相关文章
- Python进程、线程、协程的对比
1. 执行过程 每个线程有一个程序运行的入口.顺序执行序列和程序的出口.但是线程不能够独立执行,必须依存在进程中,由进程提供多个线程执行控制.每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该 ...
- Python3 进程、线程和协程
Infi-chu: http://www.cnblogs.com/Infi-chu/ 进程.线程和协程的对比 1.定义对比 进程:是系统进行资源分配的基本单位,每启动一个进程,操作系统都需要为其分配运 ...
- 协程、gevent实现异步io、进程、线程、协程对比
异步io的说白了就是遇到io操作的时候,就停下来去做别的事情.io分网络io和磁盘io,网络io比如说打开一个网站获取数据,下载一首歌等等,磁盘io就是把数据存到一个文件里面,写到磁盘上. 从网站上获 ...
- python 进程、线程与协程的区别
进程.线程与协程区别总结 - 1.进程是计算器最小资源分配单位 - 2.线程是CPU调度的最小单位 - 3.进程切换需要的资源很最大,效率很低 - 4.线程切换需要的资源一般,效率一般(当然了在不考虑 ...
- python并发编程之进程、线程、协程的调度原理(六)
进程.线程和协程的调度和运行原理总结. 系列文章 python并发编程之threading线程(一) python并发编程之multiprocessing进程(二) python并发编程之asynci ...
- 图解Python 【第八篇】:网络编程-进程、线程和协程
本节内容一览图: 本章内容: 同步和异步 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 一.同步和异步 你叫我去吃饭 ...
- python基础之进程、线程、协程篇
一.多任务(多线程) 多线程特点:(1)线程的并发是利用cpu上下文的切换(是并发,不是并行)(2)多线程执行的顺序是无序的(3)多线程共享全局变量(4)线程是继承在进程里的,没有进程就没有线程(5) ...
- Python进程、线程、协程及IO多路复用
详情戳击下方链接 Python之进程.线程.协程 python之IO多路复用
- 进程、线程、协程和GIL(二)
上一篇博客讲了进程.线程.协程和GIL的基本概念,这篇我们来说说在以下三点: 1> python中使用threading库来创建线程的两种方式 2> 使用Event对消来判断线程是否已启动 ...
随机推荐
- Linux 命令 watch 监测命令的运行结果
watch 命令周期性地执行命令,全屏显示输出命令.watch命令可以监测一个命令的运行结果 命令参数 -n, --interval 设置间隔时间.默认情况下,watch 每隔 2 秒执行一次命令. ...
- Excel透视表进阶之计算字段、计算项、切片器、页面布局
计算字段 在透视表的字段列表中通过函数.公式等方式构建一个新的字段 又称虚拟字段,因为计算字段不会出现在数据源中,对于普通字段的操作,都可以对计算字段进行操作 计算字段只能出现在值区域,不能出现在筛选 ...
- JS中的 map, filter, some, every, forEach, for in, for of 用法总结和区别
JS中的 map, filter, some, every, forEach, for in, for of 用法总结和区别 :https://blog.csdn.net/hyupeng1006/a ...
- 从入门到自闭之python初识
Day 01 整型: 对比: 在python 2 版本中有整型,长整型long 在python 3 版本中全部都是整型 用于计算和比较 整型和布尔值的转换 二进制转换成十进制: print (int ...
- python 链接mysql 事务
import mysql.connector try: con = mysql.connector.connect( host="localhost", port="33 ...
- xampp配置多域名
重要的事情: 前提: vhost.conf被引入 修改两个文件,文件所在路径,看图片上sublime编辑器,hosts和vhost.conf配置的域名必须一致 参考文档:http://blog.csd ...
- var与let变量for遍历的问题
var Liarry = document.getElementsByTagName('li'); /**方法一*描述:自执行函数,将变量当参数传入(闭包的思想,保存当前的值).*/ for (var ...
- C#判断点是否在直线上
判断点在直线上,实际上就是判断点到直线上的垂直距离.点到直线垂直距离为0,则点在线上.当然也可以误差设置误差几个像素. 参考资料并进行修改:http://blog.sina.com.cn/s/blog ...
- java 序列化原来如此
上次面试的时候 ,如何实现java 类的序列化,当时感觉这个问题很简单,我的回答是实现serizlizable 接口就好了,可以实现对象的持久化,看了看书,原来这样: public class Ser ...
- 阅读脚本控制pwm代码
在现有的项目上通过SoC的EHRPWM3B管脚产生PWM脉冲做为摄像头的framsync信号. datasheet描述: PWMSS:PWM Subsystem Resources eHRPWM: E ...