You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python threading.Lock使用异常:多线程触发不符合预期的问题排查与修复

为啥你的锁没生效?问题分析+修复方案

嘿,我来帮你捋清楚为啥代码里的锁没起作用,还触发了两个线程——主要是两个小问题在搞鬼:

1. 竞态条件:检查锁的操作不是原子的

你在thread_test里先判断if not lock.locked(),再创建线程,但这两步之间没有锁保护!当主函数里连续调用t1 = thread_test(lock)和t2 = thread_test(lock)时,第一个thread_test刚检查完锁没被占用,还没等新线程启动并拿到锁,第二个thread_test就已经完成了同样的检查,也觉得锁是空的,于是也创建了线程。这就是典型的竞态条件,两个请求抢着通过了“未锁”的检查。

2. 线程参数传递写错了

创建线程时args=(lock)这个写法有坑:括号里只放单个元素时,Python不会把它当成元组,而是直接把lock当作可迭代对象传递。正确的写法应该是args=(lock,),加个逗号,这样才是传递一个包含单个元素的元组,避免参数不匹配的问题(虽然你这里没报错,但这是个不良习惯)。

修复后的完整代码

#!/usr/bin/python 
# -*- coding:utf-8 -*- 
import time 
import threading 

def within_mutex(): 
    print "###########in mutex############" 
    n = 0 
    while n<5: 
        print "waiting ...", n 
        n += 1 
        time.sleep(1) 
    print "##########end mutex############" 

def check_thread(lock): 
    print "~~~~~~~~~~~in thread~~~~~~~~~~~~" 
    print "=====before mutex======", lock.locked() 
    with lock: 
        print "get mutex, trigger a new thread" 
        print "=====in mutex======", lock.locked() 
        within_mutex() 
    print "=====after mutex======", lock.locked() 
    print "~~~~~~~~~~~end thread~~~~~~~~~~~~" 

def thread_test(lock): 
    # 核心修复:用锁把检查+创建线程变成原子操作
    with lock:
        # 这里其实可以简化成直接创建线程(因为with已经拿到锁了),但保留你的逻辑习惯
        if not lock.locked():
            thread1 = threading.Thread(target=check_thread, args=(lock,)) 
            thread1.start() 
    print "End thread_test" 
    return 11 

if __name__ == '__main__': 
    lock = threading.Lock() 
    t1 = thread_test(lock) 
    t2 = thread_test(lock) 
    print "t1 = ",t1 
    print "t2 = ",t2 

修复逻辑说明

  • 原子化操作:在thread_test里,我用with lock:把检查锁和创建线程的代码包起来。第一个thread_test调用时会先抢到锁,完成检查和线程创建后才释放;第二个thread_test过来时,锁已经被刚启动的check_thread拿走了,所以检查lock.locked()会返回True,不会创建新线程。
  • 修正参数传递:把args=(lock)改成args=(lock,),确保参数正确传递给线程函数。

现在运行代码,就能看到只有一个线程被触发,第二个thread_test直接返回11,完全符合你的预期啦~

内容的提问来源于stack exchange,提问作者zhwlx22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:23:12