day30GIL课堂小结

昨日回顾

进程互斥锁

​ 让并发变成串行,牺牲了效率,保证效率安全.

mutex = Lock()
# 加锁
mutex.acquire()
# 释放锁
mutex.release()

队列

​ 相当于在内存中开启了一个空间,可以存放一堆数据,这堆数据都得遵循‘先进先出’.

​ 管道 (阻塞) + 锁

q = Queue()
# 添加数据
q.put(1)
# 若队列满了,会原地等待
q.put(1)
# 若队列满了,不会等待直接报错
q.put_nowait(2)

# 获取数据,遵循先进先出
若队列中没数据,会原地等待
q.get() # 1
若队列中没数据,会直接报错
q.get_nowait() # 1

q.empty() # 判断队列是否为空
q.full() # 判断队列是否满了

IPC进程间通信

​ 通过队列让进程间实现通信.

生产者与消费者

​ 生产者:生产数据的

​ 消费者:使用数据的

​ 目的:解决供需不平衡问题.

​ 通过队列来实现,生产者消费者供需不平衡问题.

线程

​ 1.什么是线程?

​ 进程:资源单位

​ 线程:执行单位

​ 注意:只要开启一个进程就会有一个线程(主线程).

​ 主线程会在进程结束时,一并销毁.

​ 2.为什么要使用线程?

​ 节省内存资

​ 开启进程:

  • 开启一个新的内存空间

  • 会自带一个主线程

    ​ 开启线程:

    • 一个进程内可以开启多个线程

    • 开启线程的资源远小于进程

# 创建线程的两种方式
一:
from threading import Thread
   def task():
       pass
   
   t = Thread(target = task) # 异步提交任务,开启线程
   t.start()
   t.join() # 主线程等待子线程结束之后再结束
   
二:
 class MyThread(Thread):
        def run(self):
         # 执行任务
            pass
        
    t = MyThread()
    t.start
    t.join()

线程对象的属性

current_thread().name # 获取当前线程对象的名字
 # 返回一个列表,列表中包含当前执行的所有线程对象
print(enumerate())
# 获取当前执行线程的个数
print(activeConunt())
is_alive() # 判断线程是否存活

线程互斥锁

from threading import Lock()
mutex = Lock()
mutex.acquire()
tl
mutex.release()

今日内容

GIL全局解释器锁

python解释器:

​ 1.Cpython:C

​ 2.Jpython:java

​ 3.Ppython:python

GIL全局解释器锁:

​ 基于Cpython来研究全局解释器锁.

​ 1.GIL本质是一个互斥锁

​ 2.GIL目的为了阻止同一个进程内多个线程同时执行(并行)

​ - 单个进程下的多个线程无法实现并行,但能实现并发

​ 3.这把锁主要是因为CPython的内存管理不是'线程安全'的.

​ - 内存管理
​ - 垃圾回收机制

GIL的存在就是为了保证线程安全的.

注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程.

多线程的作用:

​ 站在两个角度去看问题:
​ - 四个任务, 计算密集型, 每个任务需要10s:
​ 单核:
​ - 开启进程
​ 消耗资源过大
​ - 4个进程: 40s

​ - 开启线程
​ 消耗资源远小于进程
​ - 4个线程: 40s

​ 多核:
​ - 开启进程
​ 并行执行,效率比较高
​ - 4个进

原文地址:https://www.cnblogs.com/shin09/p/11730702.html