Discuss / Python / 求解!Lock锁 锁不住情况? @廖雪峰

求解!Lock锁 锁不住情况? @廖雪峰

Topic source

Lock锁失效?

1、被锁代码还是出现双线程同时执行情况,代码无误,num的值最后等于 -1 ?

import threading
import time


def example():
    global num
    lock = threading.Lock()  # 新建锁 #记住这一行    lock.acquire()

    try:
        print(1)  # 标记,通过1观察代码执行顺序        
        if num == 1:
            time.sleep(0.1)  # 延时 #记住这一行            
            num -= 1            
            print('%sTrue: %d \n' % (threading.currentThread().name, num))
        else:
            print('%sFalse: %d \n' % (threading.currentThread().name, num))
    finally:
        lock.release()


num = 1jc1 = threading.Thread(name='进程一', target=example).start()
jc2 = threading.Thread(name='进程二', target=example).start()

'''
______________上面的运行结果↓________________
1
1
进程二True: 0 
进程一True: -1 
________________________________________
'''

加入延时是为了确保在无锁的情况下双线程都能在if语句处通过,但现在加锁还是这样?

然后把 新建锁 一行位置改了一下↓

import threading
import time


def example():
    global num
    lock.acquire()

    try:
        print(1)  # 标记,通过1观察代码执行顺序        
        if num == 1:
            time.sleep(0.1)  # 延时 #记住这一行            
            num -= 1            
            print('%sTrue: %d \n' % (threading.currentThread().name, num))
        else:
            print('%sFalse: %d \n' % (threading.currentThread().name, num))
    finally:
        lock.release()


lock = threading.Lock()  # 新建锁 #记住这一行
num = 1
jc1 = threading.Thread(name='进程一', target=example).start()
jc2 = threading.Thread(name='进程二', target=example).start()




'''
______________上面的运行结果↓________________
1
进程一True: 0 

1
进程二False: 0 

________________________________________
'''

第一页粘贴的时候编排错了,

import threading
import time


def example():
    global num
    lock = threading.Lock()  # 新建锁 #记住这一行    
    lock.acquire()  # 第一页的粘贴的时候编排错了****************************

    try:
        print(1)  # 标记,通过1观察代码执行顺序        
        if num == 1:
            time.sleep(0.1)  # 延时 #记住这一行            
            num -= 1            
            print('%sTrue: %d \n' % (threading.currentThread().name, num))
        else:
            print('%sFalse: %d \n' % (threading.currentThread().name, num))
    finally:
        lock.release()


num = 1jc1 = threading.Thread(name='进程一', target=example).start()
jc2 = threading.Thread(name='进程二', target=example).start()

问题很明显,最开始的代码在example内生成锁,则两个线程只要执行都会为自己生成一个锁,那么就相当于没有锁的情况,那么第一种输出就很显然。第二种,将生成锁的代码放在外面,此时只有一个锁,每一个线程会独自执行完,则就会是预期的输出。挺明显的呀,有什么问题嘛?

4楼说的挺对的。两个线程都执行的是 example 任务,各自的任务都会在各自的线程中产生一把各自独立的锁,所以这俩锁互相没啥关系。需要把创建锁的地方放到 example 函数外。


  • 1

Reply