python 多线程 全局锁_python的多线程+GIL全局解释器锁+其他LOCK

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

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

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

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

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

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

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

1 importthreading, time2

3

4 defrun1():5 print("grab the first part data")6 lock.acquire()7 globalnum8 num += 1

9 lock.release()10 returnnum11

12

13 defrun2():14 print("grab the second part data")15 lock.acquire()16 globalnum217 num2 += 1

18 lock.release()19 returnnum220

21

22 defrun3():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 importthreading, time2

3 #信号量就是多个锁

4 defrun(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 importtime2 importthreading3

4 event =threading.Event()5 defLighter():6 count =07 event.set()8 whileTrue: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 += 1

21

22 defcar(name):23 whileTrue: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 importthreading,time2

3 importqueue4

5 q =queue.Queue()6 q.maxsize = 10

7

8 defProducer(name):9 count = 1

10 #for i in range(10):

11 whileTrue:12 q.put("骨头%s" %count) #%i)

13 print("生产了骨头",count)14 count += 1

15 time.sleep(2)16

17

18 defConsumer(name):19 whileTrue: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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值