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

Python双线程交替执行未完成且缺失步骤的问题排查与解决

问题描述

我需要实现两个线程交替执行,Thread A打印Step 1和Step 3,Thread B打印Step 2和Step 4(Python 3.8.5),预期输出:

Step 1
Step 2
Step 3
Step 4

我用全局变量、锁和while语句写了代码,但运行后只输出Step 1和Step 2,程序还一直运行不结束,没打印Step 3和Step 4。代码如下:

import threading
lock = threading.Lock()

flow = "Step 1"

def test1():
    global flow
    while True:
        while True:
            if flow == "Step 1":
                lock.acquire()
                print(flow)
                flow = "Step 2"
                lock.release()
                break
        
        while True:
            if flow == "Step 3":
                lock.acquire()
                print(flow)
                flow = "Step 4"
                lock.release()
                break
            break

def test2():
    global flow
    while True:
        while True:
            if flow == "Step 2":
                lock.acquire()
                print(flow)
                flow = "Step 3"
                lock.release()
                break
        
        while True:
            if flow == "Step 4":
                lock.acquire()
                print(flow)
                lock.release()
                break
            break

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)

t1.start()
t2.start()

t1.join()
t2.join()
问题原因
  1. test1函数的第二个内层循环逻辑错误:当flow变为Step 2后,test1进入第二个内层while循环,此时flow != Step 3,代码直接执行break跳出该循环,回到外层while True后又重新进入第一个内层循环——但此时flow是Step 2,不满足if flow == "Step 1"的条件,导致test1陷入无限空循环,永远等不到flow变为Step 3的时机。
  2. test2函数的第二个内层循环同样逻辑错误:当flow变为Step 3后,test2进入第二个内层while循环,此时flow != Step 4,直接执行break跳出循环,回到外层while True后重新进入第一个内层循环——但flow是Step 3,不满足if flow == "Step 2"的条件,test2也陷入无限空循环。
  3. 无退出条件:两个线程都陷入无限循环,没有终止逻辑,导致程序一直运行不结束。
修正方案

方案1:修复循环逻辑并添加退出条件

去掉内层循环中多余的break,让线程在条件不满足时持续等待,同时添加任务完成标记,确保线程能正常退出:

import threading
lock = threading.Lock()

flow = "Step 1"
done = False

def test1():
    global flow, done
    # 执行Step 1
    while True:
        lock.acquire()
        if flow == "Step 1":
            print(flow)
            flow = "Step 2"
            lock.release()
            break
        lock.release()
    
    # 等待并执行Step 3
    while True:
        lock.acquire()
        if flow == "Step 3":
            print(flow)
            flow = "Step 4"
            lock.release()
            break
        lock.release()
    
    # 标记任务完成
    lock.acquire()
    done = True
    lock.release()

def test2():
    global flow, done
    # 等待并执行Step 2
    while True:
        lock.acquire()
        if flow == "Step 2":
            print(flow)
            flow = "Step 3"
            lock.release()
            break
        lock.release()
    
    # 等待并执行Step 4
    while True:
        lock.acquire()
        if flow == "Step 4":
            print(flow)
            lock.release()
            break
        if done:
            lock.release()
            break
        lock.release()

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)

t1.start()
t2.start()

t1.join()
t2.join()

方案2:用threading.Condition实现高效等待通知

相比轮询全局变量,使用Condition可以更高效地实现线程间的等待与唤醒:

import threading

cond = threading.Condition()
flow = "Step 1"

def test1():
    global flow
    with cond:
        # 执行Step 1
        print("Step 1")
        flow = "Step 2"
        cond.notify()
        # 等待Step 3的信号
        cond.wait_for(lambda: flow == "Step 3")
        # 执行Step 3
        print("Step 3")
        flow = "Step 4"
        cond.notify()

def test2():
    global flow
    with cond:
        # 等待Step 2的信号
        cond.wait_for(lambda: flow == "Step 2")
        # 执行Step 2
        print("Step 2")
        flow = "Step 3"
        cond.notify()
        # 等待Step 4的信号
        cond.wait_for(lambda: flow == "Step 4")
        # 执行Step 4
        print("Step 4")

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)

t1.start()
t2.start()

t1.join()
t2.join()

内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:40:26