Как продолжить выполнение программы после того, как один из нескольких потоков вернет значение?

#python #python-3.x #multithreading #operating-system #python-multithreading

Вопрос:

В моей программе есть раздел, в котором я использую несколько потоков для моделирования распределенной среды. Все потоки пытаются взломать пароль. Как вы можете видеть, все потоки вызывают одну и ту же целевую функцию func с разными аргументами. Эта функция возвращает результат всякий trial раз, когда обнаруживается, что пароль взломан.

 def func(self, inp):
    trial = 0
    while (crackPwd(inp, trial) != True):
        trial  = 1
    return inp

threads = []

for inp in range(inpAmount):
    thr = threading.Thread(target=func, args=(inp))
    threads.append(thr)
    thr.start()

for thr in threads:
    thr.join()
 

Однако я хочу остановить другие потоки после того, как один из потоков взломает пароль. Я имею в виду, что я хочу продолжить поток программы после того, как поток вернет результат func() . Я пытался найти решение, но ни одно из них, похоже, не соответствует моей проблеме. Теперь я получил результаты от всех потоков и теряю так много времени, ожидая завершения всех потоков. Я буду признателен вам за помощь.

Ответ №1:

Не могли бы вы использовать экземпляр класса событий потоковой передачи?

Издеваясь над функцией crackPwd, упомянутой в вашем коде, чтобы спать до sleep_time 10 секунд (с вероятностью 10%) Я проверил с:

 import time
import random
import threading

def crackPwd(inp, trial):
   sleep_time = random.randint(1, 10)
   time.sleep(sleep_time)
   return sleep_time

def func(inp):
   trial = 0
   while (crackPwd(inp, trial) != 10) and (not pwd_cracked.isSet()):
      trial  = 1
   pwd_cracked.set()
   return inp

threads = []

for inp in range(10):
   pwd_cracked = threading.Event()
   thr = threading.Thread(target=func, args=(inp, ))
   threads.append(thr)
   thr.start()

for thr in threads:
   thr.join()
 

Итак, для вашего исходного кода:

 def func(self, inp):
    trial = 0
    while (crackPwd(inp, trial) != True) and (not pwd_cracked.isSet()):
        trial  = 1
    pwd_cracked.set()
    return inp

threads = []

for inp in range(inpAmount):
    pwd_cracked = threading.Event()
    thr = threading.Thread(target=func, args=(inp, ))
    threads.append(thr)
    thr.start()

for thr in threads:
    thr.join()