目录
******
socketserver自带多线程
******
每一个进程都有一个python解释器,都有一个垃圾回收机制的线程 如果没有GIL,允许多线程同时运行 线程1 执行到 a = 1,刚申请一块内存空间,把1 放进去,正要与a 绑定关系之前突然垃圾回收机制扫描到这个1 没有引用,顺手就给清除掉了,那么这个线程就直接报错了
1. GIL是python的特点吗?
不是,它只是CPython解释器的特点
2. 单进程下多个线程无法利用多核优势是所有解释型语言的通病
正确,如果解释型语言能够利用多核优势,并行地执行代码,就会出现垃圾回收机制干扰线程数据的情况,CPython中就采用了CIL全局解释器锁来解决这一问题,牺牲多核优势保证线程安全
解释型语言都需要先解释再执行,在CPython中是用GIL全局解释器锁
代码遇到I/O操作就将GIL全局解释器锁给释放了,保证线程安全但不能保证数据安全 GIL是专门保护线程安全的,要想保护数据安全需要单独为数据处理加锁(普通互斥锁通常都是这样的) 针对不同的数据操作应该加不同的锁去处理
验证GIL与普通互斥锁的区别
进程可以充分利用CPU(多核时体现),但消耗资源较(线程)大 线程较(进程)节省内存资源,但无法充分发挥多核CPU优势
计算操作很依靠CPU
单核情况下
开线程更省资源
多核情况下
开进程更省时间
IO操作不太依靠CPU(IO操作会让CPU空闲,程序进入阻塞态)
单核情况下
开线程更省资源
多核情况下
开线程更省资源(基本用不到多少CPU)
python的多线程到底有没有用,需要看情况而定,并且肯定是有用的(GIL全局解释器锁限制了python的多线程不能并行)
绝大数情况下还是多进程+多线程配合使用的
伪代码:编造代码实现效果演示一下
双方接下来要的锁都在对方手上,并且都不肯释放锁,就都在等待锁被释放再抢
自己千万不要轻易的处理锁的问题(一般也不会涉及到)
递归锁机制: RLock 可以被第一个抢到锁的人连续acquire和release多次 每acquire一次,锁身上的计数加 每release一次,锁身上的计数减1 只要锁的计数不为0,其他人都不能抢
这里的信号量不是通用概念,在不同的地方有不同的意义,对应不同的知识点
比喻
互斥锁--> 厕所(一把锁)
信号量--> 公共厕所(多把锁)
可利用event
实现子线程等待某个子线程的结束再接着执行
疑问:同一个进程下的多个线程本来就是数据共享的,为什么还要用队列? 因为队列是管道+锁,使用队列就不需要自己手动操作锁的问题,如果锁操作不当极容易产生死锁现象
三种队列 Queue LifoQueue PriorityQueue 基本操作