异步阻塞,Manager模块,线程
一、异步阻塞
1、并没有按照执行顺序等待结果
2、而是所有的任务都在异步执行着
3、但是我要的结果又不知道谁的结果先来,谁先结束我就先取谁的结果
很明显的异步,大家都相互执行着(异步过程),谁先结束我就先拿谁的结果,而我等待的过程就是一个阻塞过程,整体就是一个异步阻塞。
使用生产者消费者模型举例:
import requests
from multiprocessing import Process, Queue
url = [
'https://www.baidu.com',
'https://www.taobao.com',
'https://www.jd.com',
'https://i.cnblogs.com'
]
def producer(name, url, q): # 生产者负责爬取网页,获取状态码放进列队
ret = requests.get(url)
q.put((name, ret.status_code))
def consumer(q): # 消费者
while True:
conn = q.get()
if conn:
print(conn)
else:break
if __name__ == '__main__':
q = Queue()
p_list = []
for i in url:
p = Process(target=producer, args=(i, i, q))
p.start()
p_list.append(p)
Process(target=consumer, args=(q,)).start() # 输出
('https://www.jd.com', 200)
('https://www.baidu.com', 200)
('https://www.taobao.com', 200)
('https://i.cnblogs.com', 200)
二、Manager模块进程间数据共享(了解)
进程之间是可以实现数据共享的,通过Manager这个类就可以实现了,只不过呢实现这个数据共享的代价是非常大的,即需要对这个共享的数据进行加锁,又要去操作许多不必要的操作。
一般情况下我们不使用这种方法,使用进程的原因就是因为进程之间数据隔离,如果非要让大量数据共享,就证明这个场景不适合用进程去解决
from multiprocessing import Process, Manager, Lock
def change_dic(dic, lock):
with lock: # 使用数据共享需要加锁才能保证数据的安全,和抢票例子一样
dic['count'] -= 1
if __name__ == '__main__':
m = Manager()
lock = Lock()
dic = m.dict({'count': 100}) # 可以是字典,列表
p_l = []
for i in range(100):
p = Process(target=change_dic, args=(dic, lock))
p.start()
p_l.append(p)
for p in p_l: p.join()
print(dic) # 输出
{'count': 0}
三、线程
进程:数据隔离,资源分配的最小单位,可以利用多核,由操作系统调度,数据不安全,开启关闭切换时间开销大
进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是CPU的执行单位。
线程:数据共享,操作系统调度的最小单位,可以利用多核,由操作系统调度,数据不安全,开启关闭切换时间开销小
能被操作系统调度(给CPU执行)的最小单位,同一个进程中的多个线程同时能被CPU执行,
线程与进程的区别:
1、线程共享创建它的进程的地址空间;进程具有自己的地址空间。
2、线程可以直接访问其进程的数据;进程具有父进程数据的副本。
3、线程可以直接与进程中的其他线程通信;进程必须使用进程间通信与同级进程进行通信。
4、新线程很容易创建;新进程需要复制父进程。
5、线程可以对同一进程的线程使用相当大的控制权;进程只能控制子进程。
6、对主线程的更改可能会影响该进程对其他线程的行为;对父进程的修改不会影响子进程。
线程的特点:
1、轻型实体:线程中的实体基本不拥有系统资源。
2、独立调度和分派的基本单位:由于线程很轻,故线程的切换非常迅速且开销小(同一进程中的)。
3、共享进程资源:线程在同一进程中的各个线程,都可以共享该进程拥有的所有资源。
4、可并发执行:在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行
全局解释器锁 GIL (global interpreter lock)
在CPython中的多线程中,垃圾回收机制(gc)理解为相当于一个线程,它使用了引用计数 + 分代回收,来对变量中的引用计数为0的变量进行回收,但是如果在多线程中当CPU同时对多个线程的变量进行操作,gc 都要兼顾对每条线程的变量做引用计数,这样的话还是会造成和抢票例子一样的效果,为此诞生了一个全局解释器锁,它让每条线程中的变量要被CPU操作时,同时并且只有一条线程能被CPU操作。
全局解释器锁的出现主要是为了完成gc的回收机制,对不同线程的引用计数的变化记录更加精准
但是全局解释器锁导致了同一个进程中的多个线程只能有一个线程真正被CPU执行
节省的是io操作时间,而不是CPU计算的时间,因为CPU的计算速度非常快,大部分情况下,我们没有办法把一条进程中所有的io操作规避掉。
四、threading模块
thread模块提供了基本的线程和锁的支持,threading提供了更高级别、功能更强的线程管理的功能。
thread模块不支持守护线程,当主线进程退出时,所有的子线程不论他们是否还在工作,都会被强行退出。而threading模块支持守护线程。
线程的创建Threading. Thread类
multiprocessing模块完全模仿了threading模块的接口,二者在使用层面,有很大的相似性。
current_thread()获取当前所在的线程对象,current_thread(). ident 通过 ident 可以获取线程id
线程是不能从外部terminale
所有的子线程只能是自己执行完代码之后关闭
enumerate 列表,存储了所有活着的线程对象,包括主线程
active_count 数字,存储了所有活着的线程个数
from threading import Thread, current_thread, active_count, enumerate
import time
def func(i):
time.sleep(1)
print(f'这是线程func{i},线程id={current_thread().ident}')
t_list = []
for i in range(5):
t = Thread(target=func, args=(i,))
t.start()
t_list.append(t)
print(enumerate())
print(f'活着的线程个数{active_count()}')
for th in t_list:
th.join()
print('所有的线程都执行完了!')
# 输出
[<_MainThread(MainThread, started 8600)>, <Thread(Thread-1, started 18832)>,...]
活着的线程个数6
这是线程func3,线程id=3148
这是线程func1,线程id=2296
这是线程func0,线程id=18832
这是线程func2,线程id=18644
这是线程func4,线程id=12072
所有的线程都执行完了!
使用面向对象创建线程
from threading import Thread, current_thread
class MyThread(Thread):
def __init__(self,i):
self.i = i
super().__init__()
def run(self):
print(f'这是线程{self.i},线程号={current_thread().ident}')
t = MyThread(1)
t.start() # 开启线程,在线程中执行run方法。
# 输出
这是线程1,线程号=10160
线程之间的数据共享
修改成功说明进程的数据是共享给线程的。
from threading import Thread
count = 100
def func():
global count
count -= 1
t_list = []
for i in range(100):
t = Thread(target=func)
t.start()
t_list.append(t)
for th in t_list:
th.join()
print(f'所有的线程执行完了,count={count}')
# 输出
所有的线程执行完了,count=0
异步阻塞,Manager模块,线程的更多相关文章
- {Python之进程} 背景知识 什么是进程 进程调度 并发与并行 同步\异步\阻塞\非阻塞 进程的创建与结束 multiprocess模块 进程池和mutiprocess.Poll
Python之进程 进程 本节目录 一 背景知识 二 什么是进程 三 进程调度 四 并发与并行 五 同步\异步\阻塞\非阻塞 六 进程的创建与结束 七 multiprocess模块 八 进程池和mut ...
- 进程&线程 同步异步&阻塞非阻塞
2015-08-19 15:23:38 周三 线程 线程安全 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码 线程安全问题都是由全局变量及静态变量引起的 若每个线程中对 ...
- Python并发编程系列之常用概念剖析:并行 串行 并发 同步 异步 阻塞 非阻塞 进程 线程 协程
1 引言 并发.并行.串行.同步.异步.阻塞.非阻塞.进程.线程.协程是并发编程中的常见概念,相似却也有却不尽相同,令人头痛,这一篇博文中我们来区分一下这些概念. 2 并发与并行 在解释并发与并行之前 ...
- GIL 线程池 进程池 同步 异步 阻塞 非阻塞
1.GIL 是一个全局解释器锁,是一种互斥锁 为什么需要GIL锁:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程都要执行代码 多线程之间要竞争解释器,一旦竞争就有可能出现 ...
- python 之 并发编程(进程池与线程池、同步异步阻塞非阻塞、线程queue)
9.11 进程池与线程池 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 池子内什么时候装进程:并发的任务属于计算密集型 池子内什么时候装线程:并发的任务属于I ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
- Manager模块 队列 管道 进程池
Manager模块 作用: 多进程共享变量. Manager的字典类型: 如果value是简单类型,比如int,可以直接赋值给共享变量,并可以后续直接修改 如果value是复杂类型 ,比如list, ...
- 队列,管道,manager模块
###生产者消费者关系### 主要是解耦(高内聚,低耦合),借助队列来实现生产者消费者 模型 栈:先进后出(First In Last Out 简称:FILO) 队列:先进先出(First In Fi ...
- 同步与异步&阻塞与非阻塞
摘要 一直为同步异步,阻塞非阻塞概念所困扰,特定总结了下,原来是这么个意思 一直为同步异步,阻塞非阻塞概念所困扰,特定总结了下 一.同步与异步的区别 1.概念介绍 同步:所谓同步是一个服务的完成需要依 ...
随机推荐
- python-自定义一个序列
python的序列可以包含多个元素,开发者只要实现符合序列要求的特殊方法,就可以实现自己的序列 序列最重要的特征就是可以包含多个元素,序列有关的特使方法: __len__(self):该方法的返回值决 ...
- IPFS挖矿硬盘满了会怎样?
IPFS是一个互联网协议,对标现在的HTTP.所以,可以想见未来IPFS有多大的价值.所谓IPFS挖矿,是基于IPFS,挖的是filecoin,称其为filecoin挖矿倒是更为贴切.许多初接触IPF ...
- 攻防世界 reverse 进阶 8-The_Maya_Society Hack.lu-2017
8.The_Maya_Society Hack.lu-2017 在linux下将时间调整为2012-12-21,运行即可得到flag. 下面进行分析 1 signed __int64 __fastca ...
- 【MCU】国民N32固件库移植
目录 前言 移植N32Gxxx系列要点 前言 链接: 李柱明博客 移植AT32库&FreeRTOS教程 由于大部分国产MCU移植固件库.RTOS源码都是差不多的,所以本文不讲细节,如想熟悉移植 ...
- Topshelf一个用于使用.NET构建Windows服务框架
1 Topshelf是什么? Topshelf是用于托管使用.NET框架编写的Windows服务的框架.服务的创建得到简化,从而使开发人员可以创建一个简单的控制台应用程序,可以使用Topshelf将其 ...
- C语言之通讯录的模拟实现
C语言之通讯录的模拟实现 在C语言学习结束之际,谨以此篇文章来对C语言的学习告一段落. 纲要: 通讯录的静态版本 通讯录的动态版本 通讯录的带文件版本 因为三种实现方法除了储存形式不同,其他都基本相同 ...
- Async Cow Python 七牛异步SDK
# Async Cow Python 七牛异步SDK > gitee链接 >github链接本SDK基于官方SDK改造而成,但又对其进行了进一步封装,简化了相关操作例如:- 1.不需要使用 ...
- 文字变图片——GitHub 热点速览 v.21.14
作者:HelloGitHub-小鱼干 程序的力量,在 deep-daze 体现得淋漓尽致,你用一句话描述下你的图片需求,它就能帮你生成对应图片.同样的,appsmith 的力量在于你只要拖拽即可得到一 ...
- ELK查询命令详解总结
目录 ELK查询命令详解 倒排索引 倒排索引原理 分词器介绍及内置分词器 使用ElasticSearch API 实现CRUD 批量获取文档 使用Bulk API 实现批量操作 版本控制 什么是Map ...
- 201871030116-李小龙 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs.com/nwnu-dai ...