如何让ProcessPoolExecutor的所有Future共享变量以终止无效循环?
解决ProcessPoolExecutor暴力破解时提前终止的问题
要让所有进程感知到"所有密码已找到"并提前停止,核心是用multiprocessing.Manager创建跨进程共享的状态对象——普通全局变量在多进程中是各自独立的副本,无法同步状态。以下是具体实现方案:
方案1:共享哈希集合+结果列表
通过Manager创建共享的剩余哈希集合,每个进程循环时先检查集合是否为空,一旦为空立即退出,避免无效计算。同时用共享列表存储破解结果,替代原有的全局变量。
修改后的主函数
import multiprocessing from concurrent.futures import ProcessPoolExecutor, wait def brute_force_password() -> None: futures = [] # 使用Manager创建跨进程共享对象 with multiprocessing.Manager() as manager: # 共享集合:存储未找到的目标哈希 remaining_hashes = manager.set(PASSWORDS_TO_BRUTE_FORCE) # 共享列表:存储破解结果(对应原HACKED_PASSWORDS) hacked_passwords = manager.list([None]*len(PASSWORDS_TO_BRUTE_FORCE)) with ProcessPoolExecutor(multiprocessing.cpu_count()) as executor: # 按CPU核心数拆分8位数字的总范围(00000000-99999999) total_range = 100_000_000 interval = total_range // multiprocessing.cpu_count() for i in range(multiprocessing.cpu_count()): start = i * interval # 最后一个进程处理剩余的所有范围 end = start + interval if i != multiprocessing.cpu_count()-1 else total_range futures.append( executor.submit( check_password_in_interval, start, end, remaining_hashes, hacked_passwords, PASSWORDS_TO_BRUTE_FORCE ) ) wait(futures) # 将共享列表转为普通列表使用 global HACKED_PASSWORDS HACKED_PASSWORDS = list(hacked_passwords)
修改后的检查函数
def check_password_in_interval(start: int, end: int, remaining_hashes, hacked_passwords, target_hashes) -> None: for guess in range(start, end): # 先检查是否还有未破解的密码,没有则直接退出循环 if not remaining_hashes: break guess_str = f"{guess:08d}" hashed_guess = sha256_hash_str(guess_str) # 检查当前哈希是否在剩余目标中(进程安全操作) if hashed_guess in remaining_hashes: # 从共享集合移除,避免其他进程重复处理 remaining_hashes.remove(hashed_guess) # 找到对应索引并保存结果 index = target_hashes.index(hashed_guess) hacked_passwords[index] = guess_str print(f"{hashed_guess} is {guess_str}.")
方案2:全局停止信号(Event)
如果不需要跟踪具体剩余密码,只需要一个全局"停止"指令,可以用manager.Event():
- 主函数中创建共享Event:
stop_event = manager.Event() - 检查函数循环时先判断
stop_event.is_set(),为True则立即退出 - 当找到最后一个密码时,调用
stop_event.set()触发全局停止
这种方式实现更简洁,适合只需要整体终止的场景。
关键注意事项
- 所有跨进程共享的对象必须通过
multiprocessing.Manager创建,普通全局变量无法跨进程同步 - 共享对象的操作是进程安全的,但要避免过于频繁的锁竞争(比如不要在循环内做复杂集合操作)
- 按CPU核心数拆分破解范围,比按目标密码数量拆分更合理,能避免进程负载不均
内容的提问来源于stack exchange,提问作者sj chebou
相关产品推荐
相关产品推荐

