12.定义Lock类,用于锁定数据.三步走,锁的优缺点

#在threading模块当中定义了一个Lock类,可以方便的使用锁定:

# #1.创建锁
# mutex = threading.Lock()
#
# #2.锁定
'''
mutex.acquire(True/False)
True:如果所要获取的资源已经"锁定",表示当前线程处地等待(阻塞),直到获取到这个锁为止--默认值
False:不阻塞,即不管本次调用能够成功上锁,都不会卡在这,而是继续执行后面的代码

'''
# #3.解锁
# mutex.release()
import threading,time
#全局变量
g_num = 0
def w1():
    global g_num
    for i in range(10000000):
        #上锁
        mutexFlag = mutex.acquire(True)
        if mutexFlag:
            g_num+=1
            #解锁
            mutex.release()
    print("test1---g_num=%d"%g_num)

def w2():
    global g_num
    for i in range(10000000):
        # 上锁
        mutexFlag = mutex.acquire(True)
        if mutexFlag:
            g_num+=1
            # 解锁
            mutex.release()
    print("test2---g_num=%d" % g_num)

if __name__ == "__main__":
    #创建锁
    mutex = threading.Lock()

    t1 = threading.Thread(target=w1)
    t1.start()

    t2 = threading.Thread(target=w2)
    t2.start()

#互斥锁
'''
当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制.
线程同步能够保证多个线程安全访问,"竞争资源",最简单的同步机制就是引用互斥锁
互斥锁为资源引入一个状态:锁定/非锁定状态
某个线程要更改共享数据时,先将其锁定,此时资源的状态是锁定状态,其他线程不能更改
直到当前线程释放资源.将资源变成"非锁定"状态,其他的线程才能再次锁定该资源

互斥锁保证了每次只有一个线程进行"写操作",从而保证多个线程的正确性

上锁/解锁过程
当一个线程调用锁的acquire()方法获取琐时,锁就进行锁定"Locked"状态
每次只有一个线程可以获得这个锁,如果此时拎一个线程试图获取锁中的资源,该线程就会变成"阻塞"状态
直到拥有锁的那个线程执行release(),锁就变成"非锁定(Unlocked)"状态
线程调试程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入"运行(running)状态"

总结:
锁的好处:
1.确定了某一段代码只能由一个线程来从头到尾完整的执行
2.全局变量的安全

锁的坏处:
1.阻止了多线程的并发执行,包含锁的某段代码实际上只能以单线程模块执行,效率大大的下降了
2.由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成"死锁".

'''

 

posted @ 2018-03-22 22:59  Bob__Zhang  阅读(881)  评论(0编辑  收藏  举报