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---')