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

 

posted on 2017-08-11 14:18  momo8238  阅读(191)  评论(0编辑  收藏  举报