博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python的多线程+GIL全局解释器锁+其他LOCK
阅读量:4332 次
发布时间:2019-06-06

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

---恢复内容开始---

python的多线程实际上只有一个线程。

为了让各个线程能够平均利用CPU时间,python会计算当前已执行的微代码数量,达到一定阈值后就强制释放GIL。而这时也会触发一次操作系统的线程调度(当然是否真正进行上下文切换由操作系统自主决定)。

 

GIL全局解释器锁: 保证同一时间只有一个线程得到数据并且只有一个线程执行,但是cpu调度时间到了以后,第一个线程无论是否完成均程等待状态(若未执行完毕,数据放入寄存器中)下一线程得到的依旧是原始的公共数据。

用户级lock:保证同一时间只有一个线程在修改数据。(可以避免几个线程同时对公共原始数据进行修改,提高线程效率)

为公共数据Lock:一个线程修改后,释放,下一进程才可再次进行修改。

 

RLock(递归锁):在一个大锁中还要再包含子锁

1 import threading, time 2  3  4 def run1(): 5     print("grab the first part data") 6     lock.acquire() 7     global num 8     num += 1 9     lock.release()10     return num11 12 13 def run2():14     print("grab the second part data")15     lock.acquire()16     global num217     num2 += 118     lock.release()19     return num220 21 22 def run3():23     lock.acquire()24     res = run1()25     print('--------between run1 and run2-----')26     res2 = run2()27     lock.release()28     print(res, res2)29 30 31 # if __name__ == '__main__':32 33 num, num2 = 0, 034 lock = threading.RLock()35 for i in range(10):36     t = threading.Thread(target=run3)37     t.start()38 39 while threading.active_count() != 1:40     print(threading.active_count())41 else:42     print('----all threads done---')43     print(num, num2)

线程锁(互斥锁Mutex)

 

信号量:和单个锁的区别是信号量有多个锁

1 import threading, time 2  3 # 信号量就是多个锁 4 def run(n): 5     semaphore.acquire()#信号量获取 6     time.sleep(1) 7     print("run the thread: %s\n" % n) 8     semaphore.release() # 信号量释放 9 10 11 if __name__ == '__main__':12 13     num = 014     semaphore = threading.BoundedSemaphore(5)  # 最多允许5个线程同时运行15     for i in range(20):16         t = threading.Thread(target=run, args=(i,))17         t.start()18 19 while threading.active_count() != 1:20     pass  # print threading.active_count()21 else:22     print('----all threads done---')23     print(num)

 

事件Event:实现红绿灯

概念&涉及知识点:

事件是一个简单的同步对象;代表一个内部标志,线程可以等待设置标志,或者自己设置或清除标志。

#客户端线程可以等待设置标志      event.wait()

#a服务器线程可以设置或重置它     event.set()  event.clear()

如果设置了标志,则wait方法不会执行任何操作。

如果该标志被清除,则等待将被阻塞,直到它再次被设置为止。
任意数量的线程都可以等待同一事件。

1 import time 2 import  threading 3  4 event = threading.Event() 5 def Lighter(): 6     count = 0 7     event.set() 8     while True: 9         if count >5 and count <10: # 改成红灯10             #无标志位会显示等待,有标志位是通行。  wait是通行11             event.clear() #清空标志位12             print('\033[41;1mred light \033[0m')13         elif count >10:14             event.set() # 设置标志位,变绿灯15             count = 016         else:17             print('\033[42;1mgreen light \033[0m')18 19         time.sleep(1)20         count += 121 22 def car(name):23     while True:24         if event.is_set(): #代表绿灯25             time.sleep(1)26             print('[%s] running '%name)27         else:28             print('[%s] sees red light ,waiting '%name)29             event.wait()30             print('\033[34;1m[%s] green light is on ,start going \033[0m'%name)31 32 light = threading.Thread(target=Lighter,)33 light.start()34 35 car1 = threading.Thread(target=car,args=('Car1',))36 car1.start()

 

队列:使程序之间实现松耦合,提高处理效率。

两种模式:

 FIFO = first in first out

 LIFO = last in first out

队列和列表的区别:

队列:数据取出后,队列中就没有此数据了。

列表;数据取出进行操作,但是列表中仍旧有原数据。

 

生产者与消费者模式(做解耦):

1 import threading,time 2  3 import queue 4  5 q = queue.Queue() 6 q.maxsize = 10 7  8 def Producer(name): 9     count = 110     #for i in range(10):11     while True:12         q.put("骨头%s" %count) #%i)13         print("生产了骨头",count)14         count += 115         time.sleep(2)16 17 18 def Consumer(name):19     while True:20         print("[%s]取到[%s]并且吃了它" %(name, q.get()))21         time.sleep(1)22 23 p = threading.Thread(target=Producer, args=("lex",))24 c1 = threading.Thread(target=Consumer, args=("chen",))25 c2 = threading.Thread(target=Consumer, args=("wang",))26 27 p.start()28 c1.start()29 c2.start()

 

转载于:https://www.cnblogs.com/bocaimao/p/11212938.html

你可能感兴趣的文章
sql语言的一大类 DML 数据的操纵语言
查看>>
VMware黑屏解决方法
查看>>
JS中各种跳转解析
查看>>
JAVA 基础 / 第八课:面向对象 / JAVA类的方法与实例方法
查看>>
Ecust OJ
查看>>
P3384 【模板】树链剖分
查看>>
Thrift源码分析(二)-- 协议和编解码
查看>>
考勤系统之计算工作小时数
查看>>
4.1 分解条件式
查看>>
Equivalent Strings
查看>>
flume handler
查看>>
收藏其他博客园主写的代码,学习加自用。先表示感谢!!!
查看>>
H5 表单标签
查看>>
su 与 su - 区别
查看>>
C语言编程-9_4 字符统计
查看>>
在webconfig中写好连接后,在程序中如何调用?
查看>>
限制用户不能删除SharePoint列表中的条目(项目)
查看>>
【Linux网络编程】使用GDB调试程序
查看>>
feign调用spring clound eureka 注册中心服务
查看>>
ZT:Linux上安装JDK,最准确
查看>>