python中的非阻塞使用互斥锁

来源:互联网 发布:淘宝商务男装品牌 编辑:程序博客网 时间:2024/06/08 01:49

锁定方法acquire可以有一个blocking参数。

 

如果设定blocking为True,则当前线程会堵塞,直到获取到这个锁为止(如果没有指定,那么默认为True)

 

如果设定blocking为False,则当前线程不会堵塞

 

from threading import Thread, Lock

import time

 

num =0  #资源竞争问题

 

mutex= Lock()  #创建一个互斥锁

 

def fun1():

    global num

    for i in range(1000000):

        while True:

           # mutex.acquire(blocking=False) #通过blocking参数,如果设置为True表示acquire函数属于阻塞方式,否则,非阻塞方法

            result =mutex.acquire(False) # 通过blocking参数,如果设置为True表示acquire函数属于阻塞方式,否则,非阻塞方法

            # acquire返回值result的含义

           # 如果返回True,表示上锁成功(意思是,锁原本处于未上锁状态,此次调用成功将锁设置为上锁状态)

           #如果返回False,表示上锁失败(意思是,锁原本就属于上锁状态,此次调用再想上锁是不能完成)

            if result:

                # resultTrue,表示成功上锁,可以修改资源

                num += 1

                mutex.release()  #释放锁,表示将锁设置为打开状态

                break

            else:

                # resultFalse,表示没有成功上锁,所以尝试下一次操作

                print("线程1虽然没有拿到锁,但是可以唱歌")

                time.sleep(0.1)

 

 

def fun2():

    global num

    for i in range(1000000):

        while True:

            result = mutex.acquire(False)

            if result:

                num += 1

                mutex.release()  #释放锁,表示将锁设置为打开状态

                break

            else:

                print("线程2虽然没有拿到锁,但是可以跳舞")

                time.sleep(0.1)

 

 

t1 =Thread(target=fun1)  #创建一个线程对象

t2 =Thread(target=fun2)  #创建一个线程对象

 

t1.start()  #开启线程的执行

t2.start()

 

t1.join()  #回收线程资源

t2.join()

 

print(num)

 

上锁解锁过程

当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。

每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“阻塞”,直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。

线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。

 

锁的好处:

             

       确保了某段关键代码只能由一个线程从头到尾完整地执行

 

锁的坏处:

 

 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了

 

由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁