进程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对消来判断线程是否已启动 ...
随机推荐
- 引入父目录模块 import
a : a1.py a2.py b : b1.py 其中 a, b 同目录,现在想在b1中引用a1里面内容 在b1中需要进行进行如下操作 x = path.join('..') sys.path.ap ...
- 问题:C++类的静态成员变量如何初始化
C++类的静态成员变量属于该类,在该类所有的对象间共享. 要弄清如何初始化,首先要明白声明.定义.初始化三个概念的不同. 声明:指定变量的名字和类型,可以多次声明. 定义:为该成员变量分配存储空间,有 ...
- Android快捷键大全
参考来源:https://mp.weixin.qq.com/s/T809p17Wt8XHkbLwcQf9ow 1,Ctrl + J 快捷代码列表 2,Ctrl+Alt+O 这个快捷键可以自动导包或删 ...
- Thymeleaf模板中变量报红
在上顶部添加 <!--suppress ThymeleafVariablesResolveInspection --> 或者 <!--suppress ALL --> 都可以解 ...
- python-day14(正式学习)
目录 三元表达式 列表推导式 字典生成式 zip()方法 生成器 yield关键字 迭代套迭代 send(value) close() throw() 自定义range方法 生成器表达式 匿名函数 与 ...
- MySQL中的索引优化
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 过多的使用索引将会造成滥用.因此索引也会有它的缺点.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 ...
- 史上最全的大厂Mysql面试题在这里
1.MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联: 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中: 从:io线程——在使用star ...
- MySQL之常用SQL语句
1) 分表之后统计数据的总量 SELECT (a0.total + a1.total + a2.total + a3.total + a4.total + a5.total + a6.total + ...
- 当有多个相同的DIV时,我怎么判断我点击的是哪个
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 目标检测数据库 PASCAL 格式的 Ground Truth 的解析函数
最近在做一个目标检测算法,训练时用到了 bootstrap 策略,于是我将PASCAL的 Ground Truth 格式的读取函数从 Matlab 改写为 C++.PASCAL 的标注格式为: # P ...