锁-lock,信号量4
1. 全局解释器锁,保证同一时间只有一个线程在执行,但是由于它是把数据copy成了两份,所以
只有全局解释器锁的时候,数据加减照样出错了。
2.用户态的锁,保证同一时间,只有一个线程在真真正正地修改数据。
修改数据之前,先加一把锁。修改完了以后,释放锁。修改数据的时候,把程序变成串行的。
#主线程启动子线程之后,两者是并行的,相互之间是独立的。 import threading,time def run(n): lock.acquire() #获取一把锁 global num #把num声明成全局变量以后,才能够进行修改。 num+=1 time.sleep(1) lock.release() #释放锁 lock=threading.Lock() #生产一个锁的实例 num=0 #全局变量 t_objs=[] start_time=time.time() for i in range(10): t=threading.Thread(target=run,args=("t-%s"%i,)) t.start() t_objs.append(t) for t in t_objs: t.join() #所有线程都执行完毕 print('----All threads has finished',threading.current_thread(),threading.active_count()) print('num:',num) print('Cost time:',time.time()-start_time)
运行结果:发现确实花费了10s多。
----All threads has finished <_MainThread(MainThread, started 9908)> 1 num: 10 Cost time: 10.003000259399414 Process finished with exit code 0
3. 递归锁(又叫互斥锁),因为有多把锁,找不到出去的锁,会陷入死循环。说白了就是在一个大锁中还要再包含子锁
locks={ door1:key1, door2:key2, }
程序摘抄自老师的博客:
import threading,time def run1(): print("grab the first part data") lock.acquire() global num num +=1 lock.release() return num def run2(): print("grab the second part data") lock.acquire() global num2 num2+=1 lock.release() return num2 def run3(): lock.acquire() res = run1() print('--------between run1 and run2-----') res2 = run2() lock.release() print(res,res2) if __name__ == '__main__': num,num2 = 0,0 lock = threading.RLock() for i in range(10): t = threading.Thread(target=run3) t.start() while threading.active_count() != 1: print(threading.active_count()) else: print('----all threads done---') print(num,num2)
4.信号量Semaphore
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。最多同时有3个在执行,当有1个执行完了的时候,就会又放1个进去。发现程序是5个5个一组进行执行。
import threading, time def run(n): semaphore.acquire() time.sleep(1) print("run the thread: %s\n" % n) semaphore.release() if __name__ == '__main__': semaphore = threading.BoundedSemaphore(5) # 生成一个信号量的实例,并且定义最多允许5个线程同时运行 for i in range(20): t = threading.Thread(target=run, args=(i,)) t.start() while threading.active_count() != 1: pass # print threading.active_count() else: print('----all threads done---')