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

Python多线程异常:is_alive()始终返回False问题求助

问题

尝试实现图形界面展示多线程运行状态,线程结束时更新显示,但if threads[x].is_alive():始终返回False,尽管线程本应运行数秒。

相关代码:

def run(cmd, result, index):
    process = subprocess.Popen(cmd, stdout = subprocess.PIPE)

    process.wait()

    result[index] = str(process.communicate()).strip()

if __name__ == '__main__':

    # create 5 jobs
    threads = [None] * 5
    results = [None] * 5

    for i in range(len(threads)):
        threads[i] = threading.Thread(target=run, args=([['hashcat', "-a", "0", "-m", "0", "./crackhash" + str(i+1) + ".txt", "rockyou.txt", "--force"], results, i]))
        threads[i].start()

    for i in range(len(threads)):
        threads[i].join()

...

    # 4 - keep looping through
    while 1:
        # 5 - clear the screen before drawing it again
        screen.fill(0)
        print(threads)

        # 6 - draw the screen elements
        # element 1
        if threads[0].is_alive():
            screen.blit(text_surface, (0,0))
            screen.blit(green_button, (x - x/9, 0))
        else:
            threat_output = results[0]
            answer = get_text(results[0], "./crackhash0.txt")
            text_surface_answer = my_font.render(answer, False, (255, 255, 0))
            screen.blit(text_surface_answer, (0,0))
            screen.blit(red_button, (x - x/9, 0))
...

更新后的测试代码:

t1 = subprocess.Popen(['hashcat', "-a", "0", "-m", "0", "./crackhash0.txt", "rockyou.txt", "--force"], stdout = subprocess.PIPE)
t2 = subprocess.Popen(['hashcat', "-a", "0", "-m", "0", "./crackhash1.txt", "rockyou.txt", "--force"], stdout = subprocess.PIPE)

while 1:
    screen.fill(0)

    # check if t1 is still running
    t1_running = t1.poll()
    if t1_running is None:
        print("RUNNING")
原因分析

核心问题出在**threads[i].join()的位置**:

  • join()方法会阻塞当前线程(此处为主线程),直到目标线程完全执行完毕才会继续向下执行。
  • 启动所有线程后立刻调用循环join(),会导致主线程停在此处,等待5个线程全部跑完才进入后续GUI循环。此时再检查is_alive(),所有线程早已结束,自然返回False。

另外存在一个小bug:线程的args参数传递错误,多套了一层列表[[...], results, i],正确写法应为直接传递元组(['hashcat', ...], results, i),不过这不是导致is_alive()返回False的直接原因,但会让run函数接收的cmd参数不符合预期。

解决方案
  1. 移除join()循环:
    删除以下代码:

    for i in range(len(threads)):
        threads[i].join()
    

    这样主线程启动所有线程后会直接进入GUI循环,此时线程仍在运行,is_alive()就能正确返回True。

  2. 修正线程参数传递:
    创建线程时,args传递元组,去掉多余的外层列表:

    threads[i] = threading.Thread(target=run, args=(['hashcat', "-a", "0", "-m", "0", "./crackhash" + str(i+1) + ".txt", "rockyou.txt", "--force"], results, i))
    
  3. 可选:监控子进程状态:
    像更新后的代码那样直接监控subprocess.Popen的状态也可行,但多线程场景下需要将每个子进程对象保存,在GUI循环里逐个调用poll()判断运行状态(返回None表示进程仍在运行)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:49:13