异步阻塞,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.概念介绍 同步:所谓同步是一个服务的完成需要依 ...
随机推荐
- Hadoop企业开发场景案例,虚拟机服务器调优
Hadoop企业开发场景案例 1 案例需求 (1)需求:从1G数据中,统计每个单词出现次数.服务器3台,每台配置4G内存,4核CPU,4线程. (2)需求分析: 1G/128m = 8个M ...
- 用程序员的思维了解Filecoin
程序员接触一个新技术惯用步骤: 先搜索引擎搜索一波,找个最简单的解释.如果有了个大概的概念,就前往2.否则循环1->1->1...直到有个大概的概念为止. 上官网跑一遍. 各种论坛社区溜达 ...
- NetCore的缓存使用详例
关于我 作者博客|文章首发 缓存基础知识 缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能和可伸缩性. 缓存最适用于不经常更改的 数据,生成 成本很高. 通过缓存,可以比从数据源返回的数据的 ...
- SpringBoot-08 SpringSecurity
SpringBoot-08 SpringSecurity 创建了一个新项目,创建时选择导入starter-web 1.环境搭建 1.1 导入thymeleaf <dependency> & ...
- 「HTML+CSS」--自定义加载动画【006】
前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...
- Kubernetes 常用日志收集方案
Kubernetes 常用日志收集方案 学习了 Kubernetes 集群中监控系统的搭建,除了对集群的监控报警之外,还有一项运维工作是非常重要的,那就是日志的收集. 介绍 应用程序和系统日志可以帮助 ...
- Shell prompt(PS1) 与 Carriage Return(CR) 的关系?-- Shell十三问<第二问>
Shell prompt(PS1) 与 Carriage Return(CR) 的关系?-- Shell十三问<第二问> 当你成功登录进一个文字界面之后,大部份情形下,你会在荧幕上看到一个 ...
- redis的线程模型
一.单进程模型来处理客户端的请求 Redis 基于 Reactor 模式开发了自己的网络事件处理器: 这个处理器被称为文件事件处理器(file event handler): 文件事件处理器是单线程的 ...
- Ray Tracing in one Weekend 阅读笔记
目录 一.创建Ray类,实现背景 二.加入一个球 三.让球的颜色和其法线信息相关 四.多种形状,多个碰撞体 五.封装相机类 六.抗锯齿 七.漫发射 八.抽象出材料类(编写metal类) 九.介质材料( ...
- Centos6无法使用yum解决办法
12月后Centos 6 系统无法使用yum出现错误(文章底部看) 相信已经有一部分朋友今天连接到CentOS 6的服务器后执行yum后发现报错,那么发生了什么? CentOS 6已经随着2020年1 ...