企业门户网站模板html上线,wordpress博客页面修改,定制一款app要多少钱,云南住房和建设厅网站进程和线程的比较 1. 进程的开销比线程的开销大很多 2. 进程之间的数据是隔离的#xff0c;但是#xff0c;线程之间的数据不隔离 3. 多个进程间的线程数据不共享-----让进程通信(IPC)----进程下的线程也通信了----队列 GIL全局解释器锁(重要理论) # 虽然一个进程…进程和线程的比较 1. 进程的开销比线程的开销大很多 2. 进程之间的数据是隔离的但是线程之间的数据不隔离 3. 多个进程间的线程数据不共享-----让进程通信(IPC)----进程下的线程也通信了----队列 GIL全局解释器锁(重要理论) # 虽然一个进程中开了多个线程但在同一时刻只有一个线程在解释器中运行全局解释器 锁(GIL)来保证 # 背景信息: 1、Python代码运行在解释器上嘛有解释器来执行或者解释 2、 Python解释器的种类CPython、IPython、PyPy、Jython、IronPython 官方下载 交互式 提高速度 Java字节码 3. 当前市场使用的最多(95%)的解释器就是CPython解释器 4. GIL全局解释器锁是存在于CPython中 5. 同一时刻只有一个线程在执行GIL全局解释器锁是为了避免多个线程抢夺资源的情况 # 在设计之初在解释器上添加了一把锁 GIL 哪个线程想执行必须拿到这把锁等释放掉别的线程才能拿 ## 问题 1. python有GIL锁的原因同一个进程下多个线程实际上同一时刻只有一个线程在执行 2. 只有在python上开进程用的多其他语言一般不开多进程只开多线程就够了 3. cpython解释器开多线程不能利用多核优势只有开多进程才能利用多核优势其他语 言不存在这个问题 4. 8核cpu电脑充分利用起我这个8核 5. 如果不存在GIL锁一个进程下开启8个线程它就能够充分利用cpu资源跑满cpu 6. cpython解释器中好多代码模块都是基于GIL锁机制写起来的改不了了----》开启多 进程---》每个进程下开启的线程可以被多个cpu调度执行 7. cpython解释器io密集型使用多线程计算密集型使用多进程 互斥锁 在多线程的情况下同时执行一个数据会发生数据错乱的问题 n 10
from threading import Lock
import time
def task(lock):lock.acquire()global ntemp ntime.sleep(0.5)n temp - 1lock.release()
from threading import Threadif __name__ __main__:tt []lockLock()for i in range(10):t Thread(targettask, args(lock, ))t.start()tt.append(t)for j in tt:j.join()print(主, n) # 拿时间换空间空间换时间 时间复杂度 # 面试题既然有了GIL锁为什么还要互斥锁? (多线程下) 1. 第一个线程来了拿到a0开始执行aa1,这个时候结果a就是1了 2. 第一个线程得到的结果1还没有赋值回去给a,这个时候第二个线程来了拿到的a是 0继续执行, aa1结果还是1 3. 加了互斥锁就能够解决多线程下操作同一个数据发生错乱的问题 # 线程执行过快还未赋值下一个线程就上来了所以加个互斥锁 GIL锁同时只能执行 一 个线程 线程队列 # 队列可以解决数据隔离问题进程 队列可以保持数据的安全线程 # 线程队列1. 先进先出 2. 后进先出 3. 优先级的队列 进程
from multiprocessing import Queue
线程
import queue
queue.Queue() # queue.Queue的缺点是它的实现涉及多个锁和条件变量因此可能会影响性能和内存效率 先进先出
import queue
qqueue.Queue() # 无限大、
q.put(first)
q.put(second)
print(q.get())
print(q.get())后进先出
import queue
# Lifolast in first out
qqueue.LifoQueue()
q.put(first)
q.put(second)
print(q.get())
print(q.get()) 优先级队列
import queue
qqueue.PriorityQueue()
q.put((20,a)) # put进入一个元组,元组的第一个元素是优先级,数字越小优先级越高
q.put((10,b))
q.put((30,c))
print(q.get()) # 数字越小优先级越高,优先级高的优先出队
print(q.get())
print(q.get()) 进程池和线程池的使用(concurrent模块) # 池池子、容器类型可以盛放多个元素 # 进程池提前定义好一个池子然后往这个池子里面添加进程以后只需要往这个进 程池里面丢任务就行了然后有这个进程池里面的任意一个进程来执行任务 # 线程池由任意一个线程来执行任务 # 开进程池 def task(n, m):return nm
def task1():return {username:kevin, password:123}from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
def callback(res):print(res) # Future at 0x1ed5a5e5610 statefinished returned intprint(res.result()) # 3
def callback1(res):print(res) # Future at 0x1ed5a5e5610 statefinished returned intprint(res.result()) # {username: kevin, password: 123}print(res.result().get(username))if __name__ __main__:poolProcessPoolExecutor(3) # 定义一个进程池里面有3个进程# poolThreadPoolExecutor(3) 改一下就是线程pool.submit(task, m1, n2).add_done_callback(callback) ## 2. 往池子里面丢任务pool.submit(task1).add_done_callback(callback1) # 回调函数等执行回调用这个函数 # 拿结果print(res.result()) 进程池中先主后子如果想子进程都执行完再执行主进程 pool.shutdown() # join close
print(123) 协程理论 # 进程资源分配的基本单位 线程 执行的最小单位 协程是程序员自己想出来的不存在于操作系统中 并发切换保存状态 # 协程就是单线程下的并发 # 遇到I/O时 # 协程是最节省资源的进程是最消耗资源的其次是线程 监测有没有遇到IO本质上就是最大限度的利用CPU资源 import gevent 模块 先安装不是内置pip install gevent 猴子补丁就可以把gevent.sleep(2) 写成time.sleep(2) from gevent import monkey;
monkey.path_all() gevent.joinall([g1,g2])
# 相当于g1.join() g2.join() 今日思维导图