博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GIL解释器锁,线程补充
阅读量:4470 次
发布时间:2019-06-08

本文共 4101 字,大约阅读时间需要 13 分钟。

Gil全局解释器锁

GIL是一个互斥锁(存在于Cpython),保证数据的安全(以牺牲效率换区数据的安全性)阻止同一个进程内多个线程同时执行(不能并行但是能够实现并发)并发:发起来像是同时进行的GIL全局解释器存在的原因是CPython解释器的内存管理不是线程安全的同一个进程下多个线程不能实现并行但能实现并发,多个进程下的线程可以实现并行。在IO密集的任务中    多线程优势更为明显(开启的消耗资源少)在计算密集的任务中    多进程有优势(多CPU的优势可以提现)# 计算密集型from multiprocessing import Processfrom threading import Threadimport os,timedef work():    res=0    for i in range(100):        res*=iif __name__ == '__main__':    l=[]    print(os.cpu_count())  # 本机为8核    start=time.time()    for i in range(8):        # p=Process(target=work) #耗时9.252728939056396        p=Thread(target=work) #耗时35.369622230529785        l.append(p)        p.start()    for p in l:        p.join()    stop=time.time()    print('run time is %s' %(stop-start))#    IO密集型from multiprocessing import Processfrom threading import Threadimport threadingimport os,timedef work():    time.sleep(2)if __name__ == '__main__':    l=[]    print(os.cpu_count()) #本机为8核    start=time.time()    for i in range(600):        p=Process(target=work) #耗时4.699530839920044        # p=Thread(target=work) #耗时2.054128885269165        l.append(p)        p.start()    for p in l:        p.join()    stop=time.time()    print('run time is %s' %(stop-start))

GIL全局解释器锁与普通的互斥锁的区别

对于不同的数据,要想保证安全,需要加不同的锁处理GIL并不能保证数据的安全,它是对Cpython解释器加锁,针对的是线程,让其无法并行,保证的是同一进程下多个线程间的安全线程的互斥锁保证的是数据的安全性from threading import Thread,Lockimport timemutex=Lock()n=100def task():    global n    mutex.acquire() #如果不加自定义的锁,那么所有进程都得到了t=100的数据    t=n   #确保t得到的是修改后的n    time.sleep(0.1)    n=t-1    mutex.release()lis=[]    for i in range(100):    q=Thread(target=task)    q.start()    lis.append(q)for i in lis:    i.join()print(n)

死锁与递归锁

死锁就是两个线程或多个线程,得到了另一方需要获取的锁,而自身锁无法释放,导致线程的阻塞。递归锁就是,可以重复获取的锁(自定义锁只能获取(acquire)一次),每一次获取都会计数+1,直到计数为0的时候,锁才会释放,其他线程才可以抢锁。#死锁例子from threading import Thread,Lockimport timemutexA=Lock()mutexB=Lock()def task(name):    mutexA.acquire()#后来线程抢占了A锁,但是B锁未得到释放,无法获取    print('A get',name)    mutexB.acquire()    print('B get',name)    mutexA.release()    print('A lose',name)    mutexB.release()    print('B lose',name)    f1(name)def f1(name):    mutexB.acquire()    print('B get',name)    time.sleep(0.1) #在IO的时候,其他的线程已经抢占了A锁,而B锁并未释放    mutexA.acquire()    print('A get',name)    mutexA.release()    print('A lose',name)    mutexB.release()    print('B lose',name)    if __name__ == '__main__':    for i in range(100):        p=Thread(target=task,args=(i,))        p.start()#递归锁from threading import Thread,RLockimport timemutex=RLock()#生成一个递归锁对象class MyThread(Thread):    def run(self):        self.f1()        self.f2()    def f1(self):        mutex.acquire()        print(self.name,1)        mutex.acquire()        print(self.name,2)        mutex.release()        mutex.release()    def f2(self):        mutex.acquire()        print(self.name,3)        time.sleep(0.5)        mutex.acquire()        print(self.name,4)        mutex.release()        mutex.release()if __name__ == '__main__':    for i in range(100):        p = MyThread()        p.start()

信号量

#抢占厕所的例子from threading import Thread,Semaphoreimport timesm=Semaphore(5)#设定信号量为5,只能有5个线程可以继续执行def task(name):    with sm:        print('%s 正在上厕所')        time.sleep(5)if __name__=='__main__':    for i in range(20):        p=Thread(target=task,args=(i,))        p.start()

event时间

from threading import Event,Threadimport timeevent=Event()def light():    print('红灯亮了')    time.sleep(5)    event.set() #解除阻塞    print('绿灯亮了')def car(i):    print('%s 正在等红灯'%i)    event.wait() #阻塞    print('%s 通行'%i)    if __name__=='__main__':    t=Thread(target=light)    t.start()    for i in range(10):        c=Thread(target=car,args=(i,))        c.start()

线程queue

import queueq=queue.Queue(3)#Queue按照队列,先进先出q.put(1)q.put(2)q.put(3)print(q.get())print(q.get())print(q.get())q = queue.LifoQueue(5)#堆栈,Lifo,last in first out 先进后出q.put(1)q.put(2)q.put(3)q.put(4)print(q.get())q = queue.PriorityQueue()#PriorityQueue,优先级,数据越小,优先级越高q.put((10,'a'))  q.put((-1,'b'))q.put((100,'c'))print(q.get())print(q.get())print(q.get())# -1<10<100,所以顺序是(-1, 'b'),(10, 'a'),(100, 'c')

转载于:https://www.cnblogs.com/Mr-bear/articles/10832912.html

你可能感兴趣的文章
Sharepoint Solution Gallery Active Solution时激活按钮灰色不可用的解决方法
查看>>
教你50招提升ASP.NET性能(二十二):利用.NET 4.5异步结构
查看>>
lua连续随机数
查看>>
checkstyle使用介绍
查看>>
会了这十种Python优雅的写法,让你工作效率翻十倍,一人顶十人用!
查看>>
二维码图片生成
查看>>
在做操作系统实验的一些疑问
查看>>
Log4J日志配置详解
查看>>
NameNode 与 SecondaryNameNode 的工作机制
查看>>
Code obfuscation
查看>>
大厂资深面试官 带你破解Android高级面试
查看>>
node.js系列(实例):原生node.js实现接收前台post请求提交数据
查看>>
SignalR主动通知订阅者示例
查看>>
用python实现矩阵转置
查看>>
linux 小技巧(磁盘空间搜索)
查看>>
iOS开发——捕获崩溃信息
查看>>
(for 循环)编程找出四位整数 abcd 中满足 (ab+cd)(ab+cd)=abcd 的数
查看>>
tomcat使用spring-loaded实现应用热部署
查看>>
boost1.53中的lock-free
查看>>
链表_leetcode203
查看>>