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

如何在执行as_completed前等待ProcessPoolExecutor所有任务完成?

问题分析与解决方案

错误根源

你代码里的executor.submit(...).result()是核心问题:.result()会立即阻塞当前线程,直到该任务执行完毕并返回结果。这导致future变量存储的是任务的执行结果(比如找到的密码或None),而非Future对象。而as_completed()需要接收Future对象集合,自然会报AttributeError——因为None没有_condition属性。

快速任务(比如列表相乘)看似正常,是因为任务瞬间完成,.result()立即返回结果,这时候你误把结果当Future用,但快速任务的结果可能刚好不是None,或者没触发as_completed里的检查,但本质逻辑是错误的,只是没暴露问题而已。

解决方案

1. 修正核心逻辑(保留as_completed的提前终止优势)

去掉.result(),直接将Future对象存入字典,让as_completed正常工作。这样一旦有任务找到密码,就能立即停止所有任务,符合暴力破解的效率需求:

def main():
    start_time = time()
    cpu_cores = os.cpu_count() - LIMIT
    part_size = len(CHARACTERS)//cpu_cores
    
    password = None  # 提前初始化password变量,避免未定义报错
    for length in range(MAX_LENGTH):
        
        with Manager() as manager:
            event = manager.Event()
            
            with ProcessPoolExecutor() as executor:
                attacks = {}
                
                for part in range(cpu_cores):
                    if part == cpu_cores - 1:
                        first_bit = CHARACTERS[part_size * part :]
                    else:
                        first_bit = CHARACTERS[part_size * part : part_size * (part+1)]
                    
                    # 关键修改:去掉.result(),直接存Future对象
                    future = executor.submit(brute_force, SECRET_STRING, first_bit, event, *([CHARACTERS] * length))
                    attacks[future] =  f"Brute Force {length} - {first_bit}"
                
                for attack in as_completed(attacks):
                    try:
                        password = attack.result()
                    except Exception as e:
                        print(f"任务执行出错: {e}")
                        continue
                    if password:
                        attack_type = attacks[attack]
                        print(f"Password found by {attack_type} attack: {password}")
                        event.set()
                        break
        
        if password:
            break
        print(f"Password not found on length of {length}")
        
    end_time = time()
    duration = end_time - start_time
    print(f"Total execution time: {duration:.5f} seconds\n")

2. 如果确实需要等待所有任务完成再处理

如果你不需要提前终止,一定要等所有任务跑完再处理结果,可以用executor.shutdown(wait=True)或者concurrent.futures.wait(),但这样会浪费暴力破解的效率:

# 替换as_completed的部分代码
import concurrent.futures

futures = list(attacks.keys())
# 等待所有任务完成
concurrent.futures.wait(futures)
# 遍历所有任务结果
for future in futures:
    password = future.result()
    if password:
        attack_type = attacks[future]
        print(f"Password found by {attack_type} attack: {password}")
        break

补充说明

  • 暴力破解场景下,优先用第一种方案:一旦找到密码就触发event.set(),让其他任务检测到事件后提前退出,节省资源。
  • 注意提前初始化password变量,避免循环外引用未定义变量的报错。
  • 建议给result()加上异常捕获,避免单个任务出错导致整个程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:03:35