进程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 free 命令 查看内存使用情况
查看Linux服务器下的内存使用情况,可以使用命令free -m [root@localhost ~]$ free // 以KB为单位显示内存使用情况 [root@localhost ~]$ free ...
- 数组转字符串,字符串转数组 join(), split();
join() join() 方法用于把数组中的所有元素放入一个字符串. 元素是通过指定的分隔符进行分隔的. arrayObject.join(separator), 默认为使用逗号分隔 var ar ...
- windows jenkins 发布 springboot项目脚本
windows jenkins 发布 springboot项目脚本 1.关闭现有程序 (按端口关闭) [与按应用关闭 二选一] @echo off for /f "tokens=1-5&q ...
- C++中利用迭代器删除元素会发生什么?
转自:https://blog.csdn.net/yf_li123/article/details/75003425#comments (1)对于关联容器(如map,set,multimap,mu ...
- [官网]关于EPEL
EPEL/zh-cn https://fedoraproject.org/wiki/EPEL/zh-cn Contents [hide] 1企业版 Linux 附加软件包(EPEL) 1.1什么是企 ...
- HDU-5201 The Monkey King
题目描述 \(m\)个猴子分\(n\)个桃,要求第一个猴子的桃数严格大于其他猴子,问有多少种分法对\(1e9+7取模(\%1e9+7)\) Input \(1≤T≤25 ,1≤n,m≤100000\) ...
- pyhton自动化项目编码以及命名规范
对于任何一个编程项目来说,都需要一个编码的规范以及标准,这里整理了一些Google python的命名规范以及python语言PEP8的编码规范. 一.命名规范 命名示例: module_name, ...
- MySql 缓冲池(buffer pool) 和 写缓存(change buffer) 转
应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库. 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问. M ...
- Fire Net HDU - 1045 (二分图匹配)
题意: 给出一张图,图中'X'表示wall,'.'表示空地,可以放置blockhouse同一条直线上只能有一个blockhouse,除非有wall 隔开,问在给出的图中最多能放置多少个blockhou ...
- docker安装应用
1.docker安装oracle docker search oracle docker pull wnameless/oracle-xe-11g docker run -d -p 9090:8080 ...