GIL 信号量 event事件 线程queue
发布时间:2020-12-20 11:00:03 所属栏目:Python 来源:网络整理
导读:GIL全局解释器锁 官方解释:In CPython,the global interpreter lock, or GIL, is a mutex that prevents multiplenative threads from executing Python bytecodes at once. This lock is necessary mainlybecause CPython’s memory management is not thre
GIL全局解释器锁官方解释: In CPython,the global interpreter lock,or GIL,is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. ?
在一个python的进程内,不仅有test.py的主线程或者由该主线程开发的其他线程,还有解释器开启的来及回收等解释器级别的线程,总之,所有线程都运行在这一个进程内.
所有线程的任务,都需要将代码传给解释器去执行,所以首先要解决的是能够访问到解释器代码
? 如果多个线程的target = work name执行流程是:
多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码执行,解释器的代码是所有线程共享的,所以来及回收线程也可能访问到解释器的代码而去执行,
? 问题: python的多线程没法利用多个优势,是不是就没用了 答: 研究python的多线程是否有用需要分情况讨论 例: 1.四个计算密集型任务,每个10s 单核情况: 开线程更省资源 多核情况: 开进程 10s 开线程 40s 2.四个IO密集型任务,每个10s 单核情况: 开线程更省资源 多核情况: 开线程更省资源 ? from multiprocessing import Process from threading import Thread import time,os ? # 计算密集型 def func(): res = 0 for i in range(10000): res *= 1 ? # IO 密集型 def func(): time.sleep(3) ? if __name__ == ‘__main__‘: print(os.cpu_count()) list = [] start = time.time() for i in range(4): p = Process(target=func) # 多进程 # 计算密集型运行时间:0.21994638442993164 # IO密集型运行时间:3.2253575325012207 p = Thread(target=func) # 多线程 # 运行时间:0.003988504409790039 # IO密集型运行时间:3.0033791065216064 list.append(p) p.start() for p in list: p.join() # 等待所有子进程/子线程运行结束后再运行主进程/主线程 end = time.time() print(‘运行时间:%s‘%(end - start)) ? ? ? 死锁/递归锁指的是两个进程或线程在执行的过程中,因争抢资源而造成的一种互相等待的现象. 注意: 自己千万不要轻易处理锁 ? Rlock 递归锁 Rlock可以被第一个抢到锁的人连续的acquire和release
from threading import Thread,Lock import time ? ? # 生成两把锁 mutexA = Lock() mutexB = Lock() ? class MyThread(Thread): def run(self): self.func1() self.func2() ? def func1(self): mutexA.acquire() print(‘%s抢到了A锁‘%self.name) # self.name 等价于 current_thread(),name mutexB.acquire() print(‘%s抢到了B锁‘ % self.name) mutexB.release() print(‘%s释放了B锁‘ % self.name) mutexA.release() print(‘%s释放了A锁‘ % self.name) ? def func2(self): mutexB.acquire() print(‘%s抢到了B锁‘ % self.name) time.sleep(1) mutexA.acquire() print(‘%s抢到了A锁‘ % self.name) mutexA.release() print(‘%s释放了A锁‘ % self.name) mutexB.release() print(‘%s释放了B锁‘ % self.name) ? for i in range(10): t = MyThread() t.start() ? # 递归锁 from threading import Thread,RLock ? mutexA = mutexB = RLock() ? class MyThread(Thread): def run(self): self.func1() self.func2() ? def func1(self): mutexA.acquire() print(‘%s抢到了A锁‘%self.name) # self.name 等价于 current_thread(),name mutexB.acquire() print(‘%s抢到了B锁‘ % self.name) mutexB.release() print(‘%s释放了B锁‘ % self.name) mutexA.release() print(‘%s释放了A锁‘ % self.name) ? def func2(self): mutexB.acquire() print(‘%s抢到了B锁‘ % self.name) time.sleep(1) mutexA.acquire() print(‘%s抢到了A锁‘ % self.name) mutexA.release() print(‘%s释放了A锁‘ % self.name) mutexB.release() print(‘%s释放了B锁‘ % self.name) ? for i in range(10): t = MyThread() t.start() ? 信号量互斥锁: 一把锁一把钥匙
from threading import Thread,Semaphore import time import random ? sem = Semaphore(5) # 生成一把锁五把钥匙 ? def func(name): sem.acquire() print(‘%s进门了‘%name) time.sleep(random.randint(1,3)) sem.release() print(‘%s出门了‘%name) ? for i in range(10): t = Thread(target=func,args=(i,)) t.start() ![]() event事件e.set() 发信号
e.wait() 等待信号
? from threading import Thread,Event import time ? ? e = Event() def light(): print(‘红灯‘) time.sleep(3) e.set() print(‘绿灯‘) ? def car(name): print(‘%s等红灯‘%name) e.wait() print(‘%s开车了‘%name) ? t = Thread(target=light) t.start() ? for i in range(10): t = Thread(target=car,args=(‘车手%i‘%i,)) t.start() ? 同一个进程下的多个线程本来就是数据共享,为什么还要用队列?
import queue ? q = queue.Queue() q.put(‘one‘) q.put(‘two‘) q.put(‘three‘) print(q.get()) # >>> one 先进先出 ? q = queue.LifoQueue() q.put(‘one‘) q.put(‘two‘) q.put(‘three‘) print(q.get()) # >>> three 堆栈 先进后出 ? q = queue.PriorityQueue() # 数字越小,优先级越高 q.put((10,‘one‘)) q.put((1,‘two‘)) q.put((5,‘three‘)) print(q.get()) # >>> (1,‘two‘) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |