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参数不符合预期。
解决方案
移除
join()循环:
删除以下代码:for i in range(len(threads)): threads[i].join()这样主线程启动所有线程后会直接进入GUI循环,此时线程仍在运行,
is_alive()就能正确返回True。修正线程参数传递:
创建线程时,args传递元组,去掉多余的外层列表:threads[i] = threading.Thread(target=run, args=(['hashcat', "-a", "0", "-m", "0", "./crackhash" + str(i+1) + ".txt", "rockyou.txt", "--force"], results, i))可选:监控子进程状态:
像更新后的代码那样直接监控subprocess.Popen的状态也可行,但多线程场景下需要将每个子进程对象保存,在GUI循环里逐个调用poll()判断运行状态(返回None表示进程仍在运行)。
内容的提问来源于stack exchange,提问作者horse
相关产品推荐
相关产品推荐

